Import Tint changes from Dawn
Contains a manual fix for CMakeList.txt changes.
Changes: - b6903295a826f5378b0445c36da7859373645e45 tint/resolver: Support error cases with const-eval builti... by Ben Clayton <bclayton@google.com>
- 6fcc4f3a54eff1f2b134d0ec4fa5c69db83adb80 tint: const eval of reverseBits by Antonio Maiorano <amaiorano@google.com>
- a4314fabb471f491688b7275327cd31481d3bad7 Minor build/include fixes for google3 roll. by Loko Kung <lokokung@google.com>
- 16b4cf87d0890a0e9bd3bd41df828b8a029a4a26 Template cmake for generated files. by dan sinclair <dsinclair@chromium.org>
- 6590cc4fd929c4ed6b3043c1c6bf769de20c2a7b Add missing benchmark test. by dan sinclair <dsinclair@chromium.org>
- 8fa6c25b7868d2445413e20b3deaf117a02446ad tint: Add Initialize() / Shutdown() public APIs by Ben Clayton <bclayton@google.com>
- 02f04d914d21b30fdda5d69dea08076043be36de tint/transform: Polyfill bit-shift with RHS modulo by Ben Clayton <bclayton@google.com>
- 91e27f25f984e2156eb535421f1650c8a459fb70 Add const-eval for `floor`. by dan sinclair <dsinclair@chromium.org>
- 11cecc1e4ffb1c9604ab3d7407dc625918636354 Revert "Add CMake build option to generate intrinsic file... by dan sinclair <dsinclair@chromium.org>
- abd6a7d9d4a40c2b109cca4cc1ccd420409333bc Add const-eval for `ceil` by dan sinclair <dsinclair@chromium.org>
- 465df13196c674ebe60eaf30efc6220c88e30457 Revert "This CL updates the cmake files to use go run dir... by Dan Sinclair <dsinclair@chromium.org>
- 9cbc7e1e54b5b6385c4529cdc30f9398514aadf1 Implement const-eval for `acos` by dan sinclair <dsinclair@chromium.org>
- b3518d8b4dd9be70af0bf166bac7f5921c2725e0 Implement const eval of `abs` by dan sinclair <dsinclair@chromium.org>
- 5ae03c266a590cd119dd16e2eaaaef60b943df12 Revert "Scaffolding for generation of intrinsics files." by Dan Sinclair <dsinclair@chromium.org>
- 11f0c52bfb4bb22293f7ba867dbd33fd4f89d139 tint: const eval of extractBits by Antonio Maiorano <amaiorano@google.com>
- 58eca19f33a7068c2571a430746922faa03a0871 Add const-eval for `all`. by dan sinclair <dsinclair@chromium.org>
- aa4b64f4c8d1456a70e2f66f305457d255b952d3 tint/utils: Optimise HashmapBase::Scan() by Ben Clayton <bclayton@google.com>
- c6b381495db0bdabb8fd9eb1f33e0097099bbd7e tint/transform: Refactor transforms by Ben Clayton <bclayton@google.com>
- 336f3536e5c6b7a0b63dd7c92c58770d5a0812b5 tint: const eval of insertBits by Antonio Maiorano <amaiorano@google.com>
- e372511e1ba20f24fde0e1999fd318daeea13581 tint/utils: Rework Hashmap / Hashset by Ben Clayton <bclayton@google.com>
- 9535f7220913acd92d59c76009cb31b9410b1e21 tint/validator: Hint 'var' instead of 'const' by Ben Clayton <bclayton@google.com>
- fd9c3fe4bcedb2f1aed628c27fe6d38a768f2a89 tint/uniforimty: Remove short-circuit special-case by James Price <jrprice@google.com>
- c81f9dce07e5ea41e8aa1f65bc619b6ed669403b tint: Implement const-eval of quantizeToF16 by Ben Clayton <bclayton@google.com>
- 749abeaafb609a9d1b0be758489cc4d4bc137ba8 Revert "Add GN build option to build using generated file... by Dan Sinclair <dsinclair@chromium.org>
- a950d4539ed6e6846616804b2b986f79460bc484 This CL updates the cmake files to use go run directly. by dan sinclair <dsinclair@chromium.org>
- bdd5bbe0c5d3b0f0a1800d7ec0cf814376ec3dde tint/transform/utils: HoistToDeclBefore polish by Ben Clayton <bclayton@google.com>
- 2d63e321fd6c0342ba405204df0f978c3b3865be tint: Add callback overloads to CloneContext::Insert* by Ben Clayton <bclayton@google.com>
- b5c213b9951681beca81de2b7fda3c448df850f0 tint/resolver: Fix failures with no error by Ben Clayton <bclayton@google.com>
- 6ab5d3c1519e3b8d76598a20a5fdc3bb84d35fd2 Tint/transform: make AddBlockAttribute always do wrapping... by Zhaoming Jiang <zhaoming.jiang@intel.com>
- 2bea9055f429c3b7708b2fa33f4539c1ce98c6ad tint: Implement runtime quantizeToF16() by Ben Clayton <bclayton@google.com>
- 35da05462438b316889e88fe0f81a8e58500ee7a tint/cmake: Fix test source paths by James Price <jrprice@google.com>
- ed0649dec4f1324320d4f678819eaa48e57a5aed [IR] Fix setting of if merge target by dan sinclair <dsinclair@chromium.org>
- 9261261da87ee8bfc9564c5addec3d59cf4308e0 [IR] Add ability to dump IR graph to dot by dan sinclair <dsinclair@chromium.org>
- 1c755b68e6ff93fa734c43e5b45e4cd528c92c11 [IR] Add support for `for` statements by dan sinclair <dsinclair@chromium.org>
- 0dce067e286e3d72b929af1f06e2cc332aee2dc5 [IR] Add support for `while` statements. by dan sinclair <dsinclair@chromium.org>
- 7cd8db11558e427820d646219a69787b99e86431 Add GN build option to build using generated files. by dan sinclair <dsinclair@chromium.org>
- 50c29f6d38b3d471bc4036faae11020530538d86 [IR] Add support for `fallthrough`. by dan sinclair <dsinclair@chromium.org>
- c22b8b9dc8c058fef45c72a3c2cdd70d90fc911d Add CMake build option to generate intrinsic files. by dan sinclair <dsinclair@chromium.org>
- c02feff258e22a54de14f8afae851d0c3665e6f5 tint/cmd: Add `--rename-all` flag by Ben Clayton <bclayton@google.com>
- d336733c8338ae5bf3f4eadf9bcf8c286cd20fba [IR] Add switch control flow node. by dan sinclair <dsinclair@chromium.org>
- b9ed75cf2fe5ab8d759da17a9cfe0befb286a1a1 [IR] Track inbound branches to flow nodes. by dan sinclair <dsinclair@chromium.org>
- 6c5db2afa69756f8f07efd942c88ad5b173fc738 Scaffolding for generation of intrinsics files. by dan sinclair <dsinclair@chromium.org>
GitOrigin-RevId: b6903295a826f5378b0445c36da7859373645e45
Change-Id: Ie32c6158b8dab82f8097785131a34c44b9892986
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/108921
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: dan sinclair <dsinclair@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Ben Clayton <bclayton@chromium.org>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9d72db1..51252d2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -77,6 +77,9 @@
option_if_not_defined(TINT_BUILD_MSL_WRITER "Build the MSL output writer" ON)
option_if_not_defined(TINT_BUILD_SPV_WRITER "Build the SPIR-V output writer" ON)
option_if_not_defined(TINT_BUILD_WGSL_WRITER "Build the WGSL output writer" ON)
+
+option_if_not_defined(TINT_BUILD_IR "Build the IR" ON)
+
option_if_not_defined(TINT_BUILD_FUZZERS "Build fuzzers" OFF)
option_if_not_defined(TINT_BUILD_SPIRV_TOOLS_FUZZER "Build SPIRV-Tools fuzzer" OFF)
option_if_not_defined(TINT_BUILD_AST_FUZZER "Build AST fuzzer" OFF)
@@ -110,6 +113,7 @@
message(STATUS "Tint build MSL writer: ${TINT_BUILD_MSL_WRITER}")
message(STATUS "Tint build SPIR-V writer: ${TINT_BUILD_SPV_WRITER}")
message(STATUS "Tint build WGSL writer: ${TINT_BUILD_WGSL_WRITER}")
+message(STATUS "Tint build IR: ${TINT_BUILD_IR}")
message(STATUS "Tint build fuzzers: ${TINT_BUILD_FUZZERS}")
message(STATUS "Tint build SPIRV-Tools fuzzer: ${TINT_BUILD_SPIRV_TOOLS_FUZZER}")
message(STATUS "Tint build AST fuzzer: ${TINT_BUILD_AST_FUZZER}")
@@ -274,6 +278,7 @@
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_MSL_WRITER=$<BOOL:${TINT_BUILD_MSL_WRITER}>)
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_SPV_WRITER=$<BOOL:${TINT_BUILD_SPV_WRITER}>)
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_WGSL_WRITER=$<BOOL:${TINT_BUILD_WGSL_WRITER}>)
+ target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_IR=$<BOOL:${TINT_BUILD_IR}>)
if (COMPILER_IS_LIKE_GNU)
target_compile_options(${TARGET} PRIVATE
diff --git a/include/tint/override_id.h b/include/tint/override_id.h
index 957673d..05e56a7 100644
--- a/include/tint/override_id.h
+++ b/include/tint/override_id.h
@@ -16,6 +16,7 @@
#define SRC_TINT_OVERRIDE_ID_H_
#include <stdint.h>
+#include <functional>
namespace tint {
diff --git a/include/tint/tint.h b/include/tint/tint.h
index c7f8a8c..57a3c67 100644
--- a/include/tint/tint.h
+++ b/include/tint/tint.h
@@ -15,6 +15,9 @@
#ifndef INCLUDE_TINT_TINT_H_
#define INCLUDE_TINT_TINT_H_
+// Guard for accidental includes to private headers
+#define CURRENTLY_IN_TINT_PUBLIC_HEADER
+
// TODO(tint:88): When implementing support for an install target, all of these
// headers will need to be moved to include/tint/.
@@ -64,4 +67,16 @@
#include "src/tint/writer/glsl/generator.h"
#endif // TINT_BUILD_GLSL_WRITER
+namespace tint {
+
+/// Initialize initializes the Tint library. Call before using the Tint API.
+void Initialize();
+
+/// Shutdown uninitializes the Tint library. Call after using the Tint API.
+void Shutdown();
+
+} // namespace tint
+
+#undef CURRENTLY_IN_TINT_PUBLIC_HEADER
+
#endif // INCLUDE_TINT_TINT_H_
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 92dfe06..337b6a1 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -474,6 +474,7 @@
"symbol_table.h",
"text/unicode.cc",
"text/unicode.h",
+ "tint.cc",
"traits.h",
"transform/add_block_attribute.cc",
"transform/add_block_attribute.h",
@@ -580,6 +581,7 @@
"utils/enum_set.h",
"utils/foreach_macro.h",
"utils/hash.h",
+ "utils/hashmap_base.h",
"utils/hashmap.h",
"utils/hashset.h",
"utils/map.h",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index d4c13ca..a22d9fc 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -24,6 +24,36 @@
)
endfunction()
+set(TINT_LIB_SRCS)
+set(TINT_BENCHMARK_SRCS)
+set(TINT_TEST_SRCS)
+
+# Add a generated file set into the build.
+#
+# Params:
+# TARGET - the target name to add (without extension)
+# BENCH - set if the target has a benchmark file
+# TEST - set if the target has a test file
+#
+function(tint_generated TARGET)
+ cmake_parse_arguments(PARSE_ARGV 0 TINT_GEN "BENCH;TEST" "" "")
+
+ list(APPEND TINT_LIB_SRCS
+ ${TARGET}.cc
+ ${TARGET}.h
+ )
+ set(TINT_LIB_SRCS ${TINT_LIB_SRCS} PARENT_SCOPE)
+
+ if(${TINT_GEN_BENCH})
+ list(APPEND TINT_BENCHMARK_SRCS ${TARGET}_bench.cc)
+ set(TINT_BENCHMARK_SRCS ${TINT_BENCHMARK_SRCS} PARENT_SCOPE)
+ endif()
+ if(${TINT_GEN_TEST})
+ list(APPEND TINT_TEST_SRCS ${TARGET}_test.cc)
+ set(TINT_TEST_SRCS ${TINT_TEST_SRCS} PARENT_SCOPE)
+ endif()
+endfunction()
+
## Tint diagnostic utilities. Used by libtint and tint_utils_io.
add_library(tint_diagnostic_utils
debug.cc
@@ -46,10 +76,8 @@
PROPERTIES COMPILE_DEFINITIONS "TINT_ENABLE_BREAK_IN_DEBUGGER=1" )
endif()
-set(TINT_LIB_SRCS
+list(APPEND TINT_LIB_SRCS
../../include/tint/tint.h
- ast/access.cc
- ast/access.h
ast/alias.cc
ast/alias.h
ast/array.cc
@@ -79,8 +107,6 @@
ast/break_statement.h
ast/builtin_attribute.cc
ast/builtin_attribute.h
- ast/builtin_value.cc
- ast/builtin_value.h
ast/call_expression.cc
ast/call_expression.h
ast/call_statement.cc
@@ -107,8 +133,6 @@
ast/enable.h
ast/expression.cc
ast/expression.h
- ast/extension.cc
- ast/extension.h
ast/external_texture.cc
ast/external_texture.h
ast/f16.cc
@@ -141,8 +165,6 @@
ast/int_literal_expression.h
ast/internal_attribute.cc
ast/internal_attribute.h
- ast/interpolate_attribute.cc
- ast/interpolate_attribute.h
ast/invariant_attribute.cc
ast/invariant_attribute.h
ast/let.cc
@@ -186,8 +208,6 @@
ast/statement.h
ast/static_assert.cc
ast/static_assert.h
- ast/address_space.cc
- ast/address_space.h
ast/storage_texture.cc
ast/storage_texture.h
ast/stride_attribute.cc
@@ -204,8 +224,6 @@
ast/struct.h
ast/switch_statement.cc
ast/switch_statement.h
- ast/texel_format.cc
- ast/texel_format.h
ast/texture.cc
ast/texture.h
ast/traverse_expressions.h
@@ -248,26 +266,6 @@
inspector/resource_binding.h
inspector/scalar.cc
inspector/scalar.h
- ir/block.cc
- ir/block.h
- ir/builder.cc
- ir/builder.h
- ir/builder_impl.cc
- ir/builder_impl.h
- ir/flow_node.cc
- ir/flow_node.h
- ir/function.cc
- ir/function.h
- ir/if.cc
- ir/if.h
- ir/loop.cc
- ir/loop.h
- ir/module.cc
- ir/module.h
- ir/switch.cc
- ir/switch.h
- ir/terminator.cc
- ir/terminator.h
number.cc
number.h
program_builder.cc
@@ -283,8 +281,6 @@
resolver/const_eval.h
resolver/dependency_graph.cc
resolver/dependency_graph.h
- resolver/init_conv_intrinsic.cc
- resolver/init_conv_intrinsic.h
resolver/intrinsic_table.cc
resolver/intrinsic_table.h
resolver/intrinsic_table.inl
@@ -316,8 +312,6 @@
sem/bool.h
sem/break_if_statement.cc
sem/break_if_statement.h
- sem/builtin_type.cc
- sem/builtin_type.h
sem/builtin.cc
sem/builtin.h
sem/call_target.cc
@@ -363,8 +357,6 @@
sem/multisampled_texture.h
sem/node.cc
sem/node.h
- sem/parameter_usage.cc
- sem/parameter_usage.h
sem/pipeline_stage_set.h
sem/pointer.cc
sem/pointer.h
@@ -405,6 +397,7 @@
symbol_table.h
symbol.cc
symbol.h
+ tint.cc
text/unicode.cc
text/unicode.h
traits.h
@@ -511,6 +504,7 @@
utils/enum_set.h
utils/foreach_macro.h
utils/hash.h
+ utils/hashmap_base.h
utils/hashmap.h
utils/hashset.h
utils/map.h
@@ -541,6 +535,16 @@
writer/writer.h
)
+tint_generated(ast/access)
+tint_generated(ast/address_space BENCH TEST)
+tint_generated(ast/builtin_value BENCH TEST)
+tint_generated(ast/extension BENCH TEST)
+tint_generated(ast/interpolate_attribute)
+tint_generated(ast/texel_format BENCH TEST)
+tint_generated(resolver/init_conv_intrinsic)
+tint_generated(sem/builtin_type)
+tint_generated(sem/parameter_usage)
+
if(UNIX)
list(APPEND TINT_LIB_SRCS diagnostic/printer_linux.cc)
elseif(WIN32)
@@ -644,6 +648,33 @@
)
endif()
+if(${TINT_BUILD_IR})
+ list(APPEND TINT_LIB_SRCS
+ ir/block.cc
+ ir/block.h
+ ir/builder.cc
+ ir/builder.h
+ ir/builder_impl.cc
+ ir/builder_impl.h
+ ir/debug.cc
+ ir/debug.h
+ ir/flow_node.cc
+ ir/flow_node.h
+ ir/function.cc
+ ir/function.h
+ ir/if.cc
+ ir/if.h
+ ir/loop.cc
+ ir/loop.h
+ ir/module.cc
+ ir/module.h
+ ir/switch.cc
+ ir/switch.h
+ ir/terminator.cc
+ ir/terminator.h
+ )
+endif()
+
if(MSVC)
list(APPEND TINT_LIB_SRCS
tint.natvis
@@ -725,7 +756,7 @@
# Tests
################################################################################
if(TINT_BUILD_TESTS)
- set(TINT_TEST_SRCS
+ list(APPEND TINT_TEST_SRCS
ast/alias_test.cc
ast/array_test.cc
ast/assignment_statement_test.cc
@@ -741,7 +772,6 @@
ast/builtin_attribute_test.cc
ast/builtin_texture_helper_test.cc
ast/builtin_texture_helper_test.h
- ast/builtin_value_test.cc
ast/call_expression_test.cc
ast/call_statement_test.cc
ast/case_selector_test.cc
@@ -752,7 +782,6 @@
ast/depth_texture_test.cc
ast/discard_statement_test.cc
ast/enable_test.cc
- ast/extension_test.cc
ast/external_texture_test.cc
ast/f16_test.cc
ast/f32_test.cc
@@ -784,7 +813,6 @@
ast/sampler_test.cc
ast/stage_attribute_test.cc
ast/static_assert_test.cc
- ast/address_space_test.cc
ast/storage_texture_test.cc
ast/stride_attribute_test.cc
ast/struct_member_align_attribute_test.cc
@@ -794,7 +822,6 @@
ast/struct_test.cc
ast/switch_statement_test.cc
ast/test_helper.h
- ast/texel_format_test.cc
ast/texture_test.cc
ast/traverse_expressions_test.cc
ast/u32_test.cc
@@ -811,8 +838,6 @@
diagnostic/diagnostic_test.cc
diagnostic/formatter_test.cc
diagnostic/printer_test.cc
- ir/builder_impl_test.cc
- ir/test_helper.h
number_test.cc
program_builder_test.cc
program_test.cc
@@ -1162,9 +1187,9 @@
transform/expand_compound_assignment_test.cc
transform/first_index_offset_test.cc
transform/for_loop_to_loop_test.cc
- transform/expand_compound_assignment.cc
+ transform/expand_compound_assignment_test.cc
transform/localize_struct_array_assignment_test.cc
- transform/merge_return.cc
+ transform/merge_return_test.cc
transform/module_scope_var_to_entry_point_param_test.cc
transform/multiplanar_external_texture_test.cc
transform/num_workgroups_from_uniform_test.cc
@@ -1305,6 +1330,13 @@
)
endif()
+ if (${TINT_BUILD_IR})
+ list(APPEND TINT_TEST_SRCS
+ ir/builder_impl_test.cc
+ ir/test_helper.h
+ )
+ endif()
+
if (${TINT_BUILD_FUZZERS})
list(APPEND TINT_TEST_SRCS
fuzzers/mersenne_twister_engine.cc
@@ -1348,32 +1380,29 @@
message(FATAL_ERROR "TINT_BUILD_BENCHMARKS requires TINT_BUILD_WGSL_READER")
endif()
- set(TINT_BENCHMARK_SRC
+ list(APPEND TINT_BENCHMARK_SRCS
"castable_bench.cc"
- "ast/extension_bench.cc"
- "ast/address_space_bench.cc"
- "ast/texel_format_bench.cc"
"bench/benchmark.cc"
"reader/wgsl/parser_bench.cc"
)
if (${TINT_BUILD_GLSL_WRITER})
- list(APPEND TINT_BENCHMARK_SRC writer/glsl/generator_bench.cc)
+ list(APPEND TINT_BENCHMARK_SRCS writer/glsl/generator_bench.cc)
endif()
if (${TINT_BUILD_HLSL_WRITER})
- list(APPEND TINT_BENCHMARK_SRC writer/hlsl/generator_bench.cc)
+ list(APPEND TINT_BENCHMARK_SRCS writer/hlsl/generator_bench.cc)
endif()
if (${TINT_BUILD_MSL_WRITER})
- list(APPEND TINT_BENCHMARK_SRC writer/msl/generator_bench.cc)
+ list(APPEND TINT_BENCHMARK_SRCS writer/msl/generator_bench.cc)
endif()
if (${TINT_BUILD_SPV_WRITER})
- list(APPEND TINT_BENCHMARK_SRC writer/spirv/generator_bench.cc)
+ list(APPEND TINT_BENCHMARK_SRCS writer/spirv/generator_bench.cc)
endif()
if (${TINT_BUILD_WGSL_WRITER})
- list(APPEND TINT_BENCHMARK_SRC writer/wgsl/generator_bench.cc)
+ list(APPEND TINT_BENCHMARK_SRCS writer/wgsl/generator_bench.cc)
endif()
- add_executable(tint-benchmark ${TINT_BENCHMARK_SRC})
+ add_executable(tint-benchmark ${TINT_BENCHMARK_SRCS})
set_target_properties(${target} PROPERTIES FOLDER "Benchmarks")
tint_core_compile_options(tint-benchmark)
diff --git a/src/tint/clone_context.h b/src/tint/clone_context.h
index 8e045f5..05f4868 100644
--- a/src/tint/clone_context.h
+++ b/src/tint/clone_context.h
@@ -27,6 +27,7 @@
#include "src/tint/symbol.h"
#include "src/tint/traits.h"
#include "src/tint/utils/hashmap.h"
+#include "src/tint/utils/hashset.h"
#include "src/tint/utils/vector.h"
// Forward declarations
@@ -203,26 +204,26 @@
auto transforms = list_transforms_.Find(&from);
if (transforms) {
- for (auto* o : transforms->insert_front_) {
- to.Push(CheckedCast<T>(o));
+ for (auto& builder : transforms->insert_front_) {
+ to.Push(CheckedCast<T>(builder()));
}
for (auto& el : from) {
if (auto* insert_before = transforms->insert_before_.Find(el)) {
- for (auto insert : *insert_before) {
- to.Push(CheckedCast<T>(insert));
+ for (auto& builder : *insert_before) {
+ to.Push(CheckedCast<T>(builder()));
}
}
if (!transforms->remove_.Contains(el)) {
to.Push(Clone(el));
}
if (auto* insert_after = transforms->insert_after_.Find(el)) {
- for (auto insert : *insert_after) {
- to.Push(CheckedCast<T>(insert));
+ for (auto& builder : *insert_after) {
+ to.Push(CheckedCast<T>(builder()));
}
}
}
- for (auto* o : transforms->insert_back_) {
- to.Push(CheckedCast<T>(o));
+ for (auto& builder : transforms->insert_back_) {
+ to.Push(CheckedCast<T>(builder()));
}
} else {
for (auto& el : from) {
@@ -232,8 +233,8 @@
// transform for `from`.
if (transforms) {
if (auto* insert_after = transforms->insert_after_.Find(el)) {
- for (auto insert : *insert_after) {
- to.Push(CheckedCast<T>(insert));
+ for (auto& builder : *insert_after) {
+ to.Push(CheckedCast<T>(builder()));
}
}
}
@@ -242,8 +243,8 @@
// Clone(el) may have updated the transformation list, adding an `insert_back_`
// transform for `from`.
if (transforms) {
- for (auto* o : transforms->insert_back_) {
- to.Push(CheckedCast<T>(o));
+ for (auto& builder : transforms->insert_back_) {
+ to.Push(CheckedCast<T>(builder()));
}
}
}
@@ -374,7 +375,7 @@
return *this;
}
- /// Removes `object` from the cloned copy of `vector`.
+ /// Removes @p object from the cloned copy of @p vector.
/// @param vector the vector in #src
/// @param object a pointer to the object in #src that will be omitted from
/// the cloned vector.
@@ -392,7 +393,7 @@
return *this;
}
- /// Inserts `object` before any other objects of `vector`, when it is cloned.
+ /// Inserts @p object before any other objects of @p vector, when the vector is cloned.
/// @param vector the vector in #src
/// @param object a pointer to the object in #dst that will be inserted at the
/// front of the vector
@@ -400,11 +401,21 @@
template <typename T, size_t N, typename OBJECT>
CloneContext& InsertFront(const utils::Vector<T, N>& vector, OBJECT* object) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, object);
- list_transforms_.Edit(&vector).insert_front_.Push(object);
+ return InsertFront(vector, [object] { return object; });
+ }
+
+ /// Inserts a lazily built object before any other objects of @p vector, when the vector is
+ /// cloned.
+ /// @param vector the vector in #src
+ /// @param builder a builder of the object that will be inserted at the front of the vector.
+ /// @returns this CloneContext so calls can be chained
+ template <typename T, size_t N, typename BUILDER>
+ CloneContext& InsertFront(const utils::Vector<T, N>& vector, BUILDER&& builder) {
+ list_transforms_.Edit(&vector).insert_front_.Push(std::forward<BUILDER>(builder));
return *this;
}
- /// Inserts `object` after any other objects of `vector`, when it is cloned.
+ /// Inserts @p object after any other objects of @p vector, when the vector is cloned.
/// @param vector the vector in #src
/// @param object a pointer to the object in #dst that will be inserted at the
/// end of the vector
@@ -412,15 +423,26 @@
template <typename T, size_t N, typename OBJECT>
CloneContext& InsertBack(const utils::Vector<T, N>& vector, OBJECT* object) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, object);
- list_transforms_.Edit(&vector).insert_back_.Push(object);
+ return InsertBack(vector, [object] { return object; });
+ }
+
+ /// Inserts a lazily built object after any other objects of @p vector, when the vector is
+ /// cloned.
+ /// @param vector the vector in #src
+ /// @param builder the builder of the object in #dst that will be inserted at the end of the
+ /// vector.
+ /// @returns this CloneContext so calls can be chained
+ template <typename T, size_t N, typename BUILDER>
+ CloneContext& InsertBack(const utils::Vector<T, N>& vector, BUILDER&& builder) {
+ list_transforms_.Edit(&vector).insert_back_.Push(std::forward<BUILDER>(builder));
return *this;
}
- /// Inserts `object` before `before` whenever `vector` is cloned.
+ /// Inserts @p object before @p before whenever @p vector is cloned.
/// @param vector the vector in #src
/// @param before a pointer to the object in #src
/// @param object a pointer to the object in #dst that will be inserted before
- /// any occurrence of the clone of `before`
+ /// any occurrence of the clone of @p before
/// @returns this CloneContext so calls can be chained
template <typename T, size_t N, typename BEFORE, typename OBJECT>
CloneContext& InsertBefore(const utils::Vector<T, N>& vector,
@@ -434,15 +456,35 @@
return *this;
}
- list_transforms_.Edit(&vector).insert_before_.GetOrZero(before).Push(object);
+ list_transforms_.Edit(&vector).insert_before_.GetOrZero(before).Push(
+ [object] { return object; });
return *this;
}
- /// Inserts `object` after `after` whenever `vector` is cloned.
+ /// Inserts a lazily created object before @p before whenever @p vector is cloned.
+ /// @param vector the vector in #src
+ /// @param before a pointer to the object in #src
+ /// @param builder the builder of the object in #dst that will be inserted before any occurrence
+ /// of the clone of @p before
+ /// @returns this CloneContext so calls can be chained
+ template <typename T,
+ size_t N,
+ typename BEFORE,
+ typename BUILDER,
+ typename _ = std::enable_if_t<!std::is_pointer_v<std::decay_t<BUILDER>>>>
+ CloneContext& InsertBefore(const utils::Vector<T, N>& vector,
+ const BEFORE* before,
+ BUILDER&& builder) {
+ list_transforms_.Edit(&vector).insert_before_.GetOrZero(before).Push(
+ std::forward<BUILDER>(builder));
+ return *this;
+ }
+
+ /// Inserts @p object after @p after whenever @p vector is cloned.
/// @param vector the vector in #src
/// @param after a pointer to the object in #src
/// @param object a pointer to the object in #dst that will be inserted after
- /// any occurrence of the clone of `after`
+ /// any occurrence of the clone of @p after
/// @returns this CloneContext so calls can be chained
template <typename T, size_t N, typename AFTER, typename OBJECT>
CloneContext& InsertAfter(const utils::Vector<T, N>& vector,
@@ -456,7 +498,27 @@
return *this;
}
- list_transforms_.Edit(&vector).insert_after_.GetOrZero(after).Push(object);
+ list_transforms_.Edit(&vector).insert_after_.GetOrZero(after).Push(
+ [object] { return object; });
+ return *this;
+ }
+
+ /// Inserts a lazily created object after @p after whenever @p vector is cloned.
+ /// @param vector the vector in #src
+ /// @param after a pointer to the object in #src
+ /// @param builder the builder of the object in #dst that will be inserted after any occurrence
+ /// of the clone of @p after
+ /// @returns this CloneContext so calls can be chained
+ template <typename T,
+ size_t N,
+ typename AFTER,
+ typename BUILDER,
+ typename _ = std::enable_if_t<!std::is_pointer_v<std::decay_t<BUILDER>>>>
+ CloneContext& InsertAfter(const utils::Vector<T, N>& vector,
+ const AFTER* after,
+ BUILDER&& builder) {
+ list_transforms_.Edit(&vector).insert_after_.GetOrZero(after).Push(
+ std::forward<BUILDER>(builder));
return *this;
}
@@ -487,7 +549,7 @@
};
/// A vector of const Cloneable*
- using CloneableList = utils::Vector<const Cloneable*, 4>;
+ using CloneableBuilderList = utils::Vector<std::function<const Cloneable*()>, 4>;
/// Transformations to be applied to a list (vector)
struct ListTransforms {
@@ -495,20 +557,20 @@
utils::Hashset<const Cloneable*, 4> remove_;
/// A list of objects in #dst to insert before any others when the vector is cloned.
- CloneableList insert_front_;
+ CloneableBuilderList insert_front_;
/// A list of objects in #dst to insert after all others when the vector is cloned.
- CloneableList insert_back_;
+ CloneableBuilderList insert_back_;
/// A map of object in #src to the list of cloned objects in #dst.
/// Clone(const utils::Vector<T*>& v) will use this to insert the map-value
/// list into the target vector before cloning and inserting the map-key.
- utils::Hashmap<const Cloneable*, CloneableList, 4> insert_before_;
+ utils::Hashmap<const Cloneable*, CloneableBuilderList, 4> insert_before_;
/// A map of object in #src to the list of cloned objects in #dst.
/// Clone(const utils::Vector<T*>& v) will use this to insert the map-value
/// list into the target vector after cloning and inserting the map-key.
- utils::Hashmap<const Cloneable*, CloneableList, 4> insert_after_;
+ utils::Hashmap<const Cloneable*, CloneableBuilderList, 4> insert_after_;
};
CloneContext(const CloneContext&) = delete;
diff --git a/src/tint/clone_context_test.cc b/src/tint/clone_context_test.cc
index c895151..f2ed247 100644
--- a/src/tint/clone_context_test.cc
+++ b/src/tint/clone_context_test.cc
@@ -430,6 +430,39 @@
EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
}
+TEST_F(CloneContextNodeTest, CloneWithInsertFrontFunction) {
+ Allocator a;
+
+ ProgramBuilder builder;
+ auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
+ original_root->vec = {
+ a.Create<Node>(builder.Symbols().Register("a")),
+ a.Create<Node>(builder.Symbols().Register("b")),
+ a.Create<Node>(builder.Symbols().Register("c")),
+ };
+ Program original(std::move(builder));
+
+ ProgramBuilder cloned;
+
+ auto* cloned_root =
+ CloneContext(&cloned, &original)
+ .InsertFront(original_root->vec,
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion")); })
+ .Clone(original_root);
+
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
+
+ EXPECT_NE(cloned_root->vec[0], cloned_root->a);
+ EXPECT_NE(cloned_root->vec[1], cloned_root->b);
+ EXPECT_NE(cloned_root->vec[2], cloned_root->c);
+
+ EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
+ EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion"));
+ EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("a"));
+ EXPECT_EQ(cloned_root->vec[2]->name, cloned.Symbols().Get("b"));
+ EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
+}
+
TEST_F(CloneContextNodeTest, CloneWithInsertFront_Empty) {
Allocator a;
@@ -451,6 +484,28 @@
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion"));
}
+TEST_F(CloneContextNodeTest, CloneWithInsertFront_Empty_Function) {
+ Allocator a;
+
+ ProgramBuilder builder;
+ auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
+ original_root->vec.Clear();
+ Program original(std::move(builder));
+
+ ProgramBuilder cloned;
+
+ auto* cloned_root =
+ CloneContext(&cloned, &original)
+ .InsertFront(original_root->vec,
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion")); })
+ .Clone(original_root);
+
+ EXPECT_EQ(cloned_root->vec.Length(), 1u);
+
+ EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
+ EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion"));
+}
+
TEST_F(CloneContextNodeTest, CloneWithInsertBack) {
Allocator a;
@@ -479,6 +534,35 @@
EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("insertion"));
}
+TEST_F(CloneContextNodeTest, CloneWithInsertBack_Function) {
+ Allocator a;
+
+ ProgramBuilder builder;
+ auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
+ original_root->vec = {
+ a.Create<Node>(builder.Symbols().Register("a")),
+ a.Create<Node>(builder.Symbols().Register("b")),
+ a.Create<Node>(builder.Symbols().Register("c")),
+ };
+ Program original(std::move(builder));
+
+ ProgramBuilder cloned;
+
+ auto* cloned_root =
+ CloneContext(&cloned, &original)
+ .InsertBack(original_root->vec,
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion")); })
+ .Clone(original_root);
+
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
+
+ EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
+ EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
+ EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("b"));
+ EXPECT_EQ(cloned_root->vec[2]->name, cloned.Symbols().Get("c"));
+ EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("insertion"));
+}
+
TEST_F(CloneContextNodeTest, CloneWithInsertBack_Empty) {
Allocator a;
@@ -500,6 +584,28 @@
EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion"));
}
+TEST_F(CloneContextNodeTest, CloneWithInsertBack_Empty_Function) {
+ Allocator a;
+
+ ProgramBuilder builder;
+ auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
+ original_root->vec.Clear();
+ Program original(std::move(builder));
+
+ ProgramBuilder cloned;
+
+ auto* cloned_root =
+ CloneContext(&cloned, &original)
+ .InsertBack(original_root->vec,
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion")); })
+ .Clone(original_root);
+
+ EXPECT_EQ(cloned_root->vec.Length(), 1u);
+
+ EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
+ EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion"));
+}
+
TEST_F(CloneContextNodeTest, CloneWithInsertFrontAndBack_Empty) {
Allocator a;
@@ -509,8 +615,8 @@
Program original(std::move(builder));
ProgramBuilder cloned;
- auto* insertion_front = a.Create<Node>(cloned.Symbols().New("insertion_front"));
auto* insertion_back = a.Create<Node>(cloned.Symbols().New("insertion_back"));
+ auto* insertion_front = a.Create<Node>(cloned.Symbols().New("insertion_front"));
auto* cloned_root = CloneContext(&cloned, &original)
.InsertBack(original_root->vec, insertion_back)
@@ -524,6 +630,31 @@
EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("insertion_back"));
}
+TEST_F(CloneContextNodeTest, CloneWithInsertFrontAndBack_Empty_Function) {
+ Allocator a;
+
+ ProgramBuilder builder;
+ auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
+ original_root->vec.Clear();
+ Program original(std::move(builder));
+
+ ProgramBuilder cloned;
+
+ auto* cloned_root =
+ CloneContext(&cloned, &original)
+ .InsertBack(original_root->vec,
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion_back")); })
+ .InsertFront(original_root->vec,
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion_front")); })
+ .Clone(original_root);
+
+ EXPECT_EQ(cloned_root->vec.Length(), 2u);
+
+ EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
+ EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("insertion_front"));
+ EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("insertion_back"));
+}
+
TEST_F(CloneContextNodeTest, CloneWithInsertBefore) {
Allocator a;
@@ -552,6 +683,35 @@
EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
}
+TEST_F(CloneContextNodeTest, CloneWithInsertBefore_Function) {
+ Allocator a;
+
+ ProgramBuilder builder;
+ auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
+ original_root->vec = {
+ a.Create<Node>(builder.Symbols().Register("a")),
+ a.Create<Node>(builder.Symbols().Register("b")),
+ a.Create<Node>(builder.Symbols().Register("c")),
+ };
+ Program original(std::move(builder));
+
+ ProgramBuilder cloned;
+
+ auto* cloned_root =
+ CloneContext(&cloned, &original)
+ .InsertBefore(original_root->vec, original_root->vec[1],
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion")); })
+ .Clone(original_root);
+
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
+
+ EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
+ EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
+ EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("insertion"));
+ EXPECT_EQ(cloned_root->vec[2]->name, cloned.Symbols().Get("b"));
+ EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
+}
+
TEST_F(CloneContextNodeTest, CloneWithInsertAfter) {
Allocator a;
@@ -580,6 +740,35 @@
EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
}
+TEST_F(CloneContextNodeTest, CloneWithInsertAfter_Function) {
+ Allocator a;
+
+ ProgramBuilder builder;
+ auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
+ original_root->vec = {
+ a.Create<Node>(builder.Symbols().Register("a")),
+ a.Create<Node>(builder.Symbols().Register("b")),
+ a.Create<Node>(builder.Symbols().Register("c")),
+ };
+ Program original(std::move(builder));
+
+ ProgramBuilder cloned;
+
+ auto* cloned_root =
+ CloneContext(&cloned, &original)
+ .InsertAfter(original_root->vec, original_root->vec[1],
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion")); })
+ .Clone(original_root);
+
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
+
+ EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
+ EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
+ EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("b"));
+ EXPECT_EQ(cloned_root->vec[2]->name, cloned.Symbols().Get("insertion"));
+ EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
+}
+
TEST_F(CloneContextNodeTest, CloneWithInsertAfterInVectorNodeClone) {
Allocator a;
@@ -612,6 +801,38 @@
EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
}
+TEST_F(CloneContextNodeTest, CloneWithInsertAfterInVectorNodeClone_Function) {
+ Allocator a;
+
+ ProgramBuilder builder;
+ auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
+ original_root->vec = {
+ a.Create<Node>(builder.Symbols().Register("a")),
+ a.Create<Replaceable>(builder.Symbols().Register("b")),
+ a.Create<Node>(builder.Symbols().Register("c")),
+ };
+
+ Program original(std::move(builder));
+
+ ProgramBuilder cloned;
+ CloneContext ctx(&cloned, &original);
+ ctx.ReplaceAll([&](const Replaceable* r) {
+ ctx.InsertAfter(original_root->vec, r,
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion")); });
+ return nullptr;
+ });
+
+ auto* cloned_root = ctx.Clone(original_root);
+
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
+
+ EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
+ EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
+ EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("b"));
+ EXPECT_EQ(cloned_root->vec[2]->name, cloned.Symbols().Get("insertion"));
+ EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
+}
+
TEST_F(CloneContextNodeTest, CloneWithInsertBackInVectorNodeClone) {
Allocator a;
@@ -644,6 +865,38 @@
EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("insertion"));
}
+TEST_F(CloneContextNodeTest, CloneWithInsertBackInVectorNodeClone_Function) {
+ Allocator a;
+
+ ProgramBuilder builder;
+ auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
+ original_root->vec = {
+ a.Create<Node>(builder.Symbols().Register("a")),
+ a.Create<Replaceable>(builder.Symbols().Register("b")),
+ a.Create<Node>(builder.Symbols().Register("c")),
+ };
+
+ Program original(std::move(builder));
+
+ ProgramBuilder cloned;
+ CloneContext ctx(&cloned, &original);
+ ctx.ReplaceAll([&](const Replaceable* /*r*/) {
+ ctx.InsertBack(original_root->vec,
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion")); });
+ return nullptr;
+ });
+
+ auto* cloned_root = ctx.Clone(original_root);
+
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
+
+ EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
+ EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
+ EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("b"));
+ EXPECT_EQ(cloned_root->vec[2]->name, cloned.Symbols().Get("c"));
+ EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("insertion"));
+}
+
TEST_F(CloneContextNodeTest, CloneWithInsertBeforeAndAfterRemoved) {
Allocator a;
@@ -676,6 +929,38 @@
EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
}
+TEST_F(CloneContextNodeTest, CloneWithInsertBeforeAndAfterRemoved_Function) {
+ Allocator a;
+
+ ProgramBuilder builder;
+ auto* original_root = a.Create<Node>(builder.Symbols().Register("root"));
+ original_root->vec = {
+ a.Create<Node>(builder.Symbols().Register("a")),
+ a.Create<Node>(builder.Symbols().Register("b")),
+ a.Create<Node>(builder.Symbols().Register("c")),
+ };
+ Program original(std::move(builder));
+
+ ProgramBuilder cloned;
+
+ auto* cloned_root =
+ CloneContext(&cloned, &original)
+ .InsertBefore(original_root->vec, original_root->vec[1],
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion_before")); })
+ .InsertAfter(original_root->vec, original_root->vec[1],
+ [&] { return a.Create<Node>(cloned.Symbols().New("insertion_after")); })
+ .Remove(original_root->vec, original_root->vec[1])
+ .Clone(original_root);
+
+ EXPECT_EQ(cloned_root->vec.Length(), 4u);
+
+ EXPECT_EQ(cloned_root->name, cloned.Symbols().Get("root"));
+ EXPECT_EQ(cloned_root->vec[0]->name, cloned.Symbols().Get("a"));
+ EXPECT_EQ(cloned_root->vec[1]->name, cloned.Symbols().Get("insertion_before"));
+ EXPECT_EQ(cloned_root->vec[2]->name, cloned.Symbols().Get("insertion_after"));
+ EXPECT_EQ(cloned_root->vec[3]->name, cloned.Symbols().Get("c"));
+}
+
TEST_F(CloneContextNodeTest, CloneIntoSameBuilder) {
ProgramBuilder builder;
CloneContext ctx(&builder);
diff --git a/src/tint/cmd/main.cc b/src/tint/cmd/main.cc
index f27e643..485ca5a 100644
--- a/src/tint/cmd/main.cc
+++ b/src/tint/cmd/main.cc
@@ -26,7 +26,7 @@
#if TINT_BUILD_GLSL_WRITER
#include "StandAlone/ResourceLimits.h"
#include "glslang/Public/ShaderLang.h"
-#endif
+#endif // TINT_BUILD_GLSL_WRITER
#if TINT_BUILD_SPV_READER
#include "spirv-tools/libspirv.hpp"
@@ -39,6 +39,11 @@
#include "src/tint/val/val.h"
#include "tint/tint.h"
+#if TINT_BUILD_IR
+#include "src/tint/ir/debug.h"
+#include "src/tint/ir/module.h"
+#endif // TINT_BUILD_IR
+
namespace {
[[noreturn]] void TintInternalCompilerErrorReporter(const tint::diag::List& diagnostics) {
@@ -85,6 +90,8 @@
bool emit_single_entry_point = false;
std::string ep_name;
+ bool rename_all = false;
+
std::vector<std::string> transforms;
std::string fxc_path;
@@ -92,6 +99,10 @@
std::string xcrun_path;
std::unordered_map<std::string, double> overrides;
std::optional<tint::sem::BindingPoint> hlsl_root_constant_binding_point;
+
+#if TINT_BUILD_IR
+ bool dump_ir_graph = false;
+#endif // TINT_BUILD_IR
};
const char kUsage[] = R"(Usage: tint [options] <input-file>
@@ -131,6 +142,7 @@
--xcrun -- Path to xcrun executable, used to validate MSL output.
When specified, automatically enables MSL validation
--overrides -- Override values as IDENTIFIER=VALUE, comma-separated.
+ --rename-all -- Renames all symbols.
)";
Format parse_format(const std::string& fmt) {
@@ -433,6 +445,10 @@
return false;
}
opts->dxc_path = args[i];
+#if TINT_BUILD_IR
+ } else if (arg == "--dump-ir-graph") {
+ opts->dump_ir_graph = true;
+#endif // TINT_BUILD_IR
} else if (arg == "--xcrun") {
++i;
if (i >= args.size()) {
@@ -451,6 +467,9 @@
auto parts = split_on_equal(o);
opts->overrides.insert({parts[0], std::stod(parts[1])});
}
+ } else if (arg == "--rename-all") {
+ ++i;
+ opts->rename_all = true;
} else if (arg == "--hlsl-root-constant-binding-point") {
++i;
if (i >= args.size()) {
@@ -1129,6 +1148,11 @@
if (options.show_help) {
std::string usage = tint::utils::ReplaceAll(kUsage, "${transforms}", transform_names());
+#if TINT_BUILD_IR
+ usage +=
+ " --dump-ir-graph -- Writes the IR graph to 'tint.dot' as a dot graph\n";
+#endif // TINT_BUILD_IR
+
std::cout << usage << std::endl;
return 0;
}
@@ -1247,6 +1271,19 @@
return 1;
}
+#if TINT_BUILD_IR
+ if (options.dump_ir_graph) {
+ auto result = tint::ir::Module::FromProgram(program.get());
+ if (!result) {
+ std::cerr << "Failed to build IR from program: " << result.Failure() << std::endl;
+ } else {
+ auto mod = result.Move();
+ auto graph = tint::ir::Debug::AsDotGraph(&mod);
+ WriteFile("tint.dot", "w", graph);
+ }
+ }
+#endif // TINT_BUILD_IR
+
tint::inspector::Inspector inspector(program.get());
if (options.dump_inspector_bindings) {
@@ -1284,50 +1321,13 @@
tint::transform::Manager transform_manager;
tint::transform::DataMap transform_inputs;
- // If overrides are provided, add the SubstituteOverride transform.
- if (!options.overrides.empty()) {
- for (auto& t : transforms) {
- if (t.name == std::string("substitute_override")) {
- if (!t.make(inspector, transform_manager, transform_inputs)) {
- return 1;
- }
- break;
- }
- }
- }
-
- for (const auto& name : options.transforms) {
- // TODO(dsinclair): The vertex pulling transform requires setup code to
- // be run that needs user input. Should we find a way to support that here
- // maybe through a provided file?
-
- bool found = false;
- for (auto& t : transforms) {
- if (t.name == name) {
- if (!t.make(inspector, transform_manager, transform_inputs)) {
- return 1;
- }
- found = true;
- break;
- }
- }
- if (!found) {
- std::cerr << "Unknown transform: " << name << std::endl;
- std::cerr << "Available transforms: " << std::endl << transform_names();
- return 1;
- }
- }
-
- if (options.emit_single_entry_point) {
- transform_manager.append(std::make_unique<tint::transform::SingleEntryPoint>());
- transform_inputs.Add<tint::transform::SingleEntryPoint::Config>(options.ep_name);
- }
-
+ // Renaming must always come first
switch (options.format) {
case Format::kMsl: {
#if TINT_BUILD_MSL_WRITER
transform_inputs.Add<tint::transform::Renamer::Config>(
- tint::transform::Renamer::Target::kMslKeywords,
+ options.rename_all ? tint::transform::Renamer::Target::kAll
+ : tint::transform::Renamer::Target::kMslKeywords,
/* preserve_unicode */ false);
transform_manager.Add<tint::transform::Renamer>();
#endif // TINT_BUILD_MSL_WRITER
@@ -1335,20 +1335,63 @@
}
#if TINT_BUILD_GLSL_WRITER
case Format::kGlsl: {
+ transform_inputs.Add<tint::transform::Renamer::Config>(
+ options.rename_all ? tint::transform::Renamer::Target::kAll
+ : tint::transform::Renamer::Target::kGlslKeywords,
+ /* preserve_unicode */ false);
+ transform_manager.Add<tint::transform::Renamer>();
break;
}
#endif // TINT_BUILD_GLSL_WRITER
case Format::kHlsl: {
#if TINT_BUILD_HLSL_WRITER
transform_inputs.Add<tint::transform::Renamer::Config>(
- tint::transform::Renamer::Target::kHlslKeywords,
+ options.rename_all ? tint::transform::Renamer::Target::kAll
+ : tint::transform::Renamer::Target::kHlslKeywords,
/* preserve_unicode */ false);
transform_manager.Add<tint::transform::Renamer>();
#endif // TINT_BUILD_HLSL_WRITER
break;
}
- default:
+ default: {
+ if (options.rename_all) {
+ transform_manager.Add<tint::transform::Renamer>();
+ }
break;
+ }
+ }
+
+ auto enable_transform = [&](std::string_view name) {
+ for (auto& t : transforms) {
+ if (t.name == name) {
+ return t.make(inspector, transform_manager, transform_inputs);
+ }
+ }
+
+ std::cerr << "Unknown transform: " << name << std::endl;
+ std::cerr << "Available transforms: " << std::endl << transform_names();
+ return false;
+ };
+
+ // If overrides are provided, add the SubstituteOverride transform.
+ if (!options.overrides.empty()) {
+ if (!enable_transform("substitute_override")) {
+ return 1;
+ }
+ }
+
+ for (const auto& name : options.transforms) {
+ // TODO(dsinclair): The vertex pulling transform requires setup code to
+ // be run that needs user input. Should we find a way to support that here
+ // maybe through a provided file?
+ if (!enable_transform(name)) {
+ return 1;
+ }
+ }
+
+ if (options.emit_single_entry_point) {
+ transform_manager.append(std::make_unique<tint::transform::SingleEntryPoint>());
+ transform_inputs.Add<tint::transform::SingleEntryPoint::Config>(options.ep_name);
}
auto out = transform_manager.Run(program.get(), std::move(transform_inputs));
diff --git a/src/tint/fuzzers/shuffle_transform.cc b/src/tint/fuzzers/shuffle_transform.cc
index 5f5f6e6..6ae405a 100644
--- a/src/tint/fuzzers/shuffle_transform.cc
+++ b/src/tint/fuzzers/shuffle_transform.cc
@@ -15,6 +15,7 @@
#include "src/tint/fuzzers/shuffle_transform.h"
#include <random>
+#include <utility>
#include "src/tint/program_builder.h"
@@ -22,15 +23,21 @@
ShuffleTransform::ShuffleTransform(size_t seed) : seed_(seed) {}
-void ShuffleTransform::Run(CloneContext& ctx,
- const tint::transform::DataMap&,
- tint::transform::DataMap&) const {
- auto decls = ctx.src->AST().GlobalDeclarations();
+transform::Transform::ApplyResult ShuffleTransform::Apply(const Program* src,
+ const transform::DataMap&,
+ transform::DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
+ auto decls = src->AST().GlobalDeclarations();
auto rng = std::mt19937_64{seed_};
std::shuffle(std::begin(decls), std::end(decls), rng);
for (auto* decl : decls) {
- ctx.dst->AST().AddGlobalDeclaration(ctx.Clone(decl));
+ b.AST().AddGlobalDeclaration(ctx.Clone(decl));
}
+
+ ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::fuzzers
diff --git a/src/tint/fuzzers/shuffle_transform.h b/src/tint/fuzzers/shuffle_transform.h
index 0a64fe3..ee54f97 100644
--- a/src/tint/fuzzers/shuffle_transform.h
+++ b/src/tint/fuzzers/shuffle_transform.h
@@ -20,16 +20,16 @@
namespace tint::fuzzers {
/// ShuffleTransform reorders the module scope declarations into a random order
-class ShuffleTransform : public tint::transform::Transform {
+class ShuffleTransform : public transform::Transform {
public:
/// Constructor
/// @param seed the random seed to use for the shuffling
explicit ShuffleTransform(size_t seed);
- protected:
- void Run(CloneContext& ctx,
- const tint::transform::DataMap&,
- tint::transform::DataMap&) const override;
+ /// @copydoc transform::Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const transform::DataMap& inputs,
+ transform::DataMap& outputs) const override;
private:
size_t seed_;
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index 9a6bae2..f497405 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -404,14 +404,14 @@
////////////////////////////////////////////////////////////////////////////////
// https://gpuweb.github.io/gpuweb/wgsl/#builtin-functions
-fn abs<T: fiu32_f16>(T) -> T
-fn abs<N: num, T: fiu32_f16>(vec<N, T>) -> vec<N, T>
-fn acos<T: f32_f16>(T) -> T
-fn acos<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+@const fn abs<T: fia_fiu32_f16>(T) -> T
+@const fn abs<N: num, T: fia_fiu32_f16>(vec<N, T>) -> vec<N, T>
+@const fn acos<T: fa_f32_f16>(@test_value(0.87758256189) T) -> T
+@const fn acos<N: num, T: fa_f32_f16>(@test_value(0.87758256189) vec<N, T>) -> vec<N, T>
fn acosh<T: f32_f16>(T) -> T
fn acosh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
-fn all(bool) -> bool
-fn all<N: num>(vec<N, bool>) -> bool
+@const fn all(bool) -> bool
+@const fn all<N: num>(vec<N, bool>) -> bool
@const fn any(bool) -> bool
@const fn any<N: num>(vec<N, bool>) -> bool
fn arrayLength<T, A: access>(ptr<storage, array<T>, A>) -> u32
@@ -425,8 +425,8 @@
@const fn atan2<T: fa_f32_f16, N: num>(vec<N, T>, vec<N, T>) -> vec<N, T>
@const fn atanh<T: fa_f32_f16>(@test_value(0.5) T) -> T
@const fn atanh<N: num, T: fa_f32_f16>(@test_value(0.5) vec<N, T>) -> vec<N, T>
-fn ceil<T: f32_f16>(T) -> T
-fn ceil<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+@const fn ceil<T: fa_f32_f16>(@test_value(1.5) T) -> T
+@const fn ceil<N: num, T: fa_f32_f16>(@test_value(1.5) vec<N, T>) -> vec<N, T>
@const fn clamp<T: fia_fiu32_f16>(T, T, T) -> T
@const fn clamp<T: fia_fiu32_f16, N: num>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
fn cos<T: f32_f16>(T) -> T
@@ -464,15 +464,15 @@
fn exp<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
fn exp2<T: f32_f16>(T) -> T
fn exp2<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
-fn extractBits<T: iu32>(T, u32, u32) -> T
-fn extractBits<N: num, T: iu32>(vec<N, T>, u32, u32) -> vec<N, T>
+@const fn extractBits<T: iu32>(T, u32, u32) -> T
+@const fn extractBits<N: num, T: iu32>(vec<N, T>, u32, u32) -> vec<N, T>
fn faceForward<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
@const fn firstLeadingBit<T: iu32>(T) -> T
@const fn firstLeadingBit<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
@const fn firstTrailingBit<T: iu32>(T) -> T
@const fn firstTrailingBit<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
-fn floor<T: f32_f16>(T) -> T
-fn floor<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+@const fn floor<T: fa_f32_f16>(@test_value(1.5) T) -> T
+@const fn floor<N: num, T: fa_f32_f16>(@test_value(1.5) vec<N, T>) -> vec<N, T>
fn fma<T: f32_f16>(T, T, T) -> T
fn fma<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
fn fract<T: f32_f16>(T) -> T
@@ -485,8 +485,8 @@
@stage("fragment") fn fwidthCoarse<N: num>(vec<N, f32>) -> vec<N, f32>
@stage("fragment") fn fwidthFine(f32) -> f32
@stage("fragment") fn fwidthFine<N: num>(vec<N, f32>) -> vec<N, f32>
-fn insertBits<T: iu32>(T, T, u32, u32) -> T
-fn insertBits<N: num, T: iu32>(vec<N, T>, vec<N, T>, u32, u32) -> vec<N, T>
+@const fn insertBits<T: iu32>(T, T, u32, u32) -> T
+@const fn insertBits<N: num, T: iu32>(vec<N, T>, vec<N, T>, u32, u32) -> vec<N, T>
fn inverseSqrt<T: f32_f16>(T) -> T
fn inverseSqrt<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
fn ldexp<T: f32_f16>(T, i32) -> T
@@ -514,12 +514,14 @@
fn pack4x8unorm(vec4<f32>) -> u32
fn pow<T: f32_f16>(T, T) -> T
fn pow<N: num, T: f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
+@const fn quantizeToF16(f32) -> f32
+@const fn quantizeToF16<N: num>(vec<N, f32>) -> vec<N, f32>
fn radians<T: f32_f16>(T) -> T
fn radians<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
fn reflect<N: num, T: f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
fn refract<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T>
-fn reverseBits<T: iu32>(T) -> T
-fn reverseBits<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
+@const fn reverseBits<T: iu32>(T) -> T
+@const fn reverseBits<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
fn round<T: f32_f16>(T) -> T
fn round<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
@const fn saturate<T: fa_f32_f16>(@test_value(2) T) -> T
diff --git a/src/tint/ir/builder.cc b/src/tint/ir/builder.cc
index 66b195b..851d2d6 100644
--- a/src/tint/ir/builder.cc
+++ b/src/tint/ir/builder.cc
@@ -39,35 +39,58 @@
auto* ir_func = ir.flow_nodes.Create<Function>(ast_func);
ir_func->start_target = CreateBlock();
ir_func->end_target = CreateTerminator();
+
+ // Function is always branching into the start target
+ ir_func->start_target->inbound_branches.Push(ir_func);
+
return ir_func;
}
-If* Builder::CreateIf(const ast::Statement* stmt, IfFlags flags) {
+If* Builder::CreateIf(const ast::Statement* stmt) {
auto* ir_if = ir.flow_nodes.Create<If>(stmt);
- ir_if->false_target = CreateBlock();
ir_if->true_target = CreateBlock();
+ ir_if->false_target = CreateBlock();
+ ir_if->merge_target = CreateBlock();
- if (flags == IfFlags::kCreateMerge) {
- ir_if->merge_target = CreateBlock();
- } else {
- ir_if->merge_target = nullptr;
- }
+ // An if always branches to both the true and false block.
+ ir_if->true_target->inbound_branches.Push(ir_if);
+ ir_if->false_target->inbound_branches.Push(ir_if);
+
return ir_if;
}
-Loop* Builder::CreateLoop(const ast::LoopStatement* stmt) {
+Loop* Builder::CreateLoop(const ast::Statement* stmt) {
auto* ir_loop = ir.flow_nodes.Create<Loop>(stmt);
ir_loop->start_target = CreateBlock();
ir_loop->continuing_target = CreateBlock();
ir_loop->merge_target = CreateBlock();
+ // A loop always branches to the start block.
+ ir_loop->start_target->inbound_branches.Push(ir_loop);
+
return ir_loop;
}
-void Builder::Branch(Block* from, const FlowNode* to) {
+Switch* Builder::CreateSwitch(const ast::SwitchStatement* stmt) {
+ auto* ir_switch = ir.flow_nodes.Create<Switch>(stmt);
+ ir_switch->merge_target = CreateBlock();
+ return ir_switch;
+}
+
+Block* Builder::CreateCase(Switch* s, const utils::VectorRef<const ast::CaseSelector*> selectors) {
+ s->cases.Push(Switch::Case{selectors, CreateBlock()});
+
+ Block* b = s->cases.Back().start_target;
+ // Switch branches into the case block
+ b->inbound_branches.Push(s);
+ return b;
+}
+
+void Builder::Branch(Block* from, FlowNode* to) {
TINT_ASSERT(IR, from);
TINT_ASSERT(IR, to);
from->branch_target = to;
+ to->inbound_branches.Push(from);
}
} // namespace tint::ir
diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h
index 531bcce..cf0de70 100644
--- a/src/tint/ir/builder.h
+++ b/src/tint/ir/builder.h
@@ -26,6 +26,9 @@
namespace tint {
class Program;
} // namespace tint
+namespace tint::ast {
+class CaseSelector;
+} // namespace tint::ast
namespace tint::ir {
@@ -52,30 +55,31 @@
/// @returns the flow node
Function* CreateFunction(const ast::Function* func);
- /// Flags used for creation of if flow nodes
- enum class IfFlags {
- /// Do not create a merge node, `merge_target` will be `nullptr`
- kSkipMerge,
- /// Create the `merge_target` block
- kCreateMerge,
- };
-
/// Creates an if flow node for the given ast::IfStatement or ast::BreakIfStatement
/// @param stmt the ast::IfStatement or ast::BreakIfStatement
- /// @param flags the if creation flags. By default the merge block will not be created, pass
- /// IfFlags::kCreateMerge if creation is desired.
/// @returns the flow node
- If* CreateIf(const ast::Statement* stmt, IfFlags flags = IfFlags::kSkipMerge);
+ If* CreateIf(const ast::Statement* stmt);
- /// Creates a loop flow node for the given ast::LoopStatement
- /// @param stmt the ast::LoopStatement
+ /// Creates a loop flow node for the given ast loop, while or for statement
+ /// @param stmt the ast loop, while or for statement
/// @returns the flow node
- Loop* CreateLoop(const ast::LoopStatement* stmt);
+ Loop* CreateLoop(const ast::Statement* stmt);
+
+ /// Creates a switch flow node for the given ast::SwitchStatement
+ /// @param stmt the ast::SwitchStatment
+ /// @returns the flow node
+ Switch* CreateSwitch(const ast::SwitchStatement* stmt);
+
+ /// Creates a case flow node for the given case branch.
+ /// @param s the switch to create the case into
+ /// @param selectors the case selectors for the case statement
+ /// @returns the start block for the case flow node
+ Block* CreateCase(Switch* s, const utils::VectorRef<const ast::CaseSelector*> selectors);
/// Branches the given block to the given flow node.
/// @param from the block to branch from
/// @param to the node to branch too
- void Branch(Block* from, const FlowNode* to);
+ void Branch(Block* from, FlowNode* to);
/// The IR module.
Module ir;
diff --git a/src/tint/ir/builder_impl.cc b/src/tint/ir/builder_impl.cc
index 5f7553f..6bbcf6d 100644
--- a/src/tint/ir/builder_impl.cc
+++ b/src/tint/ir/builder_impl.cc
@@ -19,11 +19,16 @@
#include "src/tint/ast/break_if_statement.h"
#include "src/tint/ast/break_statement.h"
#include "src/tint/ast/continue_statement.h"
+#include "src/tint/ast/fallthrough_statement.h"
+#include "src/tint/ast/for_loop_statement.h"
#include "src/tint/ast/function.h"
#include "src/tint/ast/if_statement.h"
+#include "src/tint/ast/loop_statement.h"
#include "src/tint/ast/return_statement.h"
#include "src/tint/ast/statement.h"
#include "src/tint/ast/static_assert.h"
+#include "src/tint/ast/switch_statement.h"
+#include "src/tint/ast/while_statement.h"
#include "src/tint/ir/function.h"
#include "src/tint/ir/if.h"
#include "src/tint/ir/loop.h"
@@ -50,23 +55,41 @@
BuilderImpl* impl_;
};
+bool IsBranched(const Block* b) {
+ return b->branch_target != nullptr;
+}
+
+bool IsConnected(const FlowNode* b) {
+ // Function is always connected as it's the start.
+ if (b->Is<ir::Function>()) {
+ return true;
+ }
+
+ for (auto* parent : b->inbound_branches) {
+ if (IsConnected(parent)) {
+ return true;
+ }
+ }
+ // Getting here means all the incoming branches are disconnected.
+ return false;
+}
+
} // namespace
BuilderImpl::BuilderImpl(const Program* program) : builder_(program) {}
BuilderImpl::~BuilderImpl() = default;
-void BuilderImpl::BranchTo(const FlowNode* node) {
+void BuilderImpl::BranchTo(FlowNode* node) {
TINT_ASSERT(IR, current_flow_block_);
- TINT_ASSERT(IR, !current_flow_block_->branch_target);
+ TINT_ASSERT(IR, !IsBranched(current_flow_block_));
builder_.Branch(current_flow_block_, node);
- current_flow_block_->branch_target = node;
current_flow_block_ = nullptr;
}
-void BuilderImpl::BranchToIfNeeded(const FlowNode* node) {
- if (!current_flow_block_ || current_flow_block_->branch_target) {
+void BuilderImpl::BranchToIfNeeded(FlowNode* node) {
+ if (!current_flow_block_ || IsBranched(current_flow_block_)) {
return;
}
BranchTo(node);
@@ -115,8 +138,10 @@
return true;
},
[&](Default) {
- TINT_ICE(IR, diagnostics_) << "unhandled type: " << decl->TypeInfo().name;
- return false;
+ diagnostics_.add_warning(tint::diag::System::IR,
+ "unknown type: " + std::string(decl->TypeInfo().name),
+ decl->source);
+ return true;
});
if (!ok) {
return utils::Failure;
@@ -168,7 +193,7 @@
// If the current flow block has a branch target then the rest of the statements in this
// block are dead code. Skip them.
- if (!current_flow_block_ || current_flow_block_->branch_target) {
+ if (!current_flow_block_ || IsBranched(current_flow_block_)) {
break;
}
}
@@ -185,21 +210,22 @@
// [&](const ast::CallStatement* c) { },
[&](const ast::ContinueStatement* c) { return EmitContinue(c); },
// [&](const ast::DiscardStatement* d) { },
- // [&](const ast::FallthroughStatement*) { },
+ [&](const ast::FallthroughStatement*) { return EmitFallthrough(); },
[&](const ast::IfStatement* i) { return EmitIf(i); },
[&](const ast::LoopStatement* l) { return EmitLoop(l); },
- // [&](const ast::ForLoopStatement* l) { },
- // [&](const ast::WhileStatement* l) { },
+ [&](const ast::ForLoopStatement* l) { return EmitForLoop(l); },
+ [&](const ast::WhileStatement* l) { return EmitWhile(l); },
[&](const ast::ReturnStatement* r) { return EmitReturn(r); },
- // [&](const ast::SwitchStatement* s) { },
+ [&](const ast::SwitchStatement* s) { return EmitSwitch(s); },
// [&](const ast::VariableDeclStatement* v) { },
[&](const ast::StaticAssert*) {
return true; // Not emitted
},
[&](Default) {
- TINT_ICE(IR, diagnostics_)
- << "unknown statement type: " << std::string(stmt->TypeInfo().name);
- return false;
+ diagnostics_.add_warning(
+ tint::diag::System::IR,
+ "unknown statement type: " + std::string(stmt->TypeInfo().name), stmt->source);
+ return true;
});
}
@@ -228,31 +254,23 @@
if (!EmitStatement(stmt->body)) {
return false;
}
+ // If the true branch did not execute control flow, then go to the merge target
+ BranchToIfNeeded(if_node->merge_target);
current_flow_block_ = if_node->false_target;
if (stmt->else_statement && !EmitStatement(stmt->else_statement)) {
return false;
}
+ // If the false branch did not execute control flow, then go to the merge target
+ BranchToIfNeeded(if_node->merge_target);
}
current_flow_block_ = nullptr;
// If both branches went somewhere, then they both returned, continued or broke. So,
// there is no need for the if merge-block and there is nothing to branch to the merge
// block anyway.
- if (if_node->true_target->branch_target && if_node->false_target->branch_target) {
- return true;
- }
-
- if_node->merge_target = builder_.CreateBlock();
- current_flow_block_ = if_node->merge_target;
-
- // If the true branch did not execute control flow, then go to the merge target
- if (!if_node->true_target->branch_target) {
- if_node->true_target->branch_target = if_node->merge_target;
- }
- // If the false branch did not execute control flow, then go to the merge target
- if (!if_node->false_target->branch_target) {
- if_node->false_target->branch_target = if_node->merge_target;
+ if (IsConnected(if_node->merge_target)) {
+ current_flow_block_ = if_node->merge_target;
}
return true;
@@ -287,7 +305,143 @@
BranchToIfNeeded(loop_node->start_target);
}
+ // The loop merge can get disconnected if the loop returns directly, or the continuing target
+ // branches, eventually, to the merge, but nothing branched to the continuing target.
current_flow_block_ = loop_node->merge_target;
+ if (!IsConnected(loop_node->merge_target)) {
+ current_flow_block_ = nullptr;
+ }
+ return true;
+}
+
+bool BuilderImpl::EmitWhile(const ast::WhileStatement* stmt) {
+ auto* loop_node = builder_.CreateLoop(stmt);
+ // Continue is always empty, just go back to the start
+ builder_.Branch(loop_node->continuing_target, loop_node->start_target);
+
+ BranchTo(loop_node);
+
+ ast_to_flow_[stmt] = loop_node;
+
+ {
+ FlowStackScope scope(this, loop_node);
+
+ current_flow_block_ = loop_node->start_target;
+
+ // TODO(dsinclair): Emit the instructions for the condition
+
+ // Create an if (cond) {} else {break;} control flow
+ auto* if_node = builder_.CreateIf(nullptr);
+ builder_.Branch(if_node->true_target, if_node->merge_target);
+ builder_.Branch(if_node->false_target, loop_node->merge_target);
+ // TODO(dsinclair): set if condition register into if flow node
+
+ BranchTo(if_node);
+
+ current_flow_block_ = if_node->merge_target;
+ if (!EmitStatement(stmt->body)) {
+ return false;
+ }
+
+ BranchToIfNeeded(loop_node->continuing_target);
+ }
+ // The while loop always has a path to the merge target as the break statement comes before
+ // anything inside the loop.
+ current_flow_block_ = loop_node->merge_target;
+ return true;
+}
+
+bool BuilderImpl::EmitForLoop(const ast::ForLoopStatement* stmt) {
+ auto* loop_node = builder_.CreateLoop(stmt);
+ builder_.Branch(loop_node->continuing_target, loop_node->start_target);
+
+ if (stmt->initializer) {
+ // Emit the for initializer before branching to the loop
+ if (!EmitStatement(stmt->initializer)) {
+ return false;
+ }
+ }
+
+ BranchTo(loop_node);
+
+ ast_to_flow_[stmt] = loop_node;
+
+ {
+ FlowStackScope scope(this, loop_node);
+
+ current_flow_block_ = loop_node->start_target;
+
+ if (stmt->condition) {
+ // TODO(dsinclair): Emit the instructions for the condition
+
+ // Create an if (cond) {} else {break;} control flow
+ auto* if_node = builder_.CreateIf(nullptr);
+ builder_.Branch(if_node->true_target, if_node->merge_target);
+ builder_.Branch(if_node->false_target, loop_node->merge_target);
+ // TODO(dsinclair): set if condition register into if flow node
+
+ BranchTo(if_node);
+ current_flow_block_ = if_node->merge_target;
+ }
+
+ if (!EmitStatement(stmt->body)) {
+ return false;
+ }
+
+ BranchToIfNeeded(loop_node->continuing_target);
+
+ if (stmt->continuing) {
+ current_flow_block_ = loop_node->continuing_target;
+ if (!EmitStatement(stmt->continuing)) {
+ return false;
+ }
+ }
+ }
+ // The while loop always has a path to the merge target as the break statement comes before
+ // anything inside the loop.
+ current_flow_block_ = loop_node->merge_target;
+ return true;
+}
+
+bool BuilderImpl::EmitSwitch(const ast::SwitchStatement* stmt) {
+ auto* switch_node = builder_.CreateSwitch(stmt);
+
+ // TODO(dsinclair): Emit the condition expression into the current block
+
+ BranchTo(switch_node);
+
+ ast_to_flow_[stmt] = switch_node;
+
+ {
+ FlowStackScope scope(this, switch_node);
+
+ // TODO(crbug.com/tint/1644): This can be simplifed when fallthrough is removed, a single
+ // loop can be used to iterate each body statement and emit for the case. Two loops are
+ // needed in order to have the target for a fallthrough.
+ for (const auto* c : stmt->body) {
+ builder_.CreateCase(switch_node, c->selectors);
+ }
+
+ for (size_t i = 0; i < stmt->body.Length(); ++i) {
+ current_flow_block_ = switch_node->cases[i].start_target;
+ if (i < (stmt->body.Length() - 1)) {
+ fallthrough_target_ = switch_node->cases[i + 1].start_target;
+ }
+
+ if (!EmitStatement(stmt->body[i]->body)) {
+ return false;
+ }
+ BranchToIfNeeded(switch_node->merge_target);
+
+ fallthrough_target_ = nullptr;
+ }
+ }
+ current_flow_block_ = nullptr;
+
+ if (IsConnected(switch_node->merge_target)) {
+ current_flow_block_ = switch_node->merge_target;
+ }
+
return true;
}
@@ -295,10 +449,6 @@
// TODO(dsinclair): Emit the return value ....
BranchTo(current_function_->end_target);
-
- // TODO(dsinclair): The BranchTo will reset the current block. What happens with dead code
- // after the return?
-
return true;
}
@@ -315,8 +465,6 @@
return false;
}
- // TODO(dsinclair): The BranchTo will reset the current block. What happens with dead code
- // after the break?
return true;
}
@@ -330,14 +478,11 @@
TINT_UNREACHABLE(IR, diagnostics_);
}
- // TODO(dsinclair): The BranchTo will reset the current block. What happens with dead code
- // after the continue?
-
return true;
}
bool BuilderImpl::EmitBreakIf(const ast::BreakIfStatement* stmt) {
- auto* if_node = builder_.CreateIf(stmt, Builder::IfFlags::kCreateMerge);
+ auto* if_node = builder_.CreateIf(stmt);
// TODO(dsinclair): Emit the condition expression into the current block
@@ -369,4 +514,10 @@
return true;
}
+bool BuilderImpl::EmitFallthrough() {
+ TINT_ASSERT(IR, fallthrough_target_ != nullptr);
+ BranchTo(fallthrough_target_);
+ return true;
+}
+
} // namespace tint::ir
diff --git a/src/tint/ir/builder_impl.h b/src/tint/ir/builder_impl.h
index 8daeebc..d6c4bc4 100644
--- a/src/tint/ir/builder_impl.h
+++ b/src/tint/ir/builder_impl.h
@@ -34,11 +34,13 @@
class BreakIfStatement;
class BreakStatement;
class ContinueStatement;
+class ForLoopStatement;
class Function;
class IfStatement;
class LoopStatement;
class ReturnStatement;
class Statement;
+class WhileStatement;
} // namespace tint::ast
namespace tint::ir {
class Block;
@@ -102,21 +104,40 @@
/// @returns true if successful, false otherwise.
bool EmitLoop(const ast::LoopStatement* stmt);
+ /// Emits a loop control node to the IR.
+ /// @param stmt the while statement
+ /// @returns true if successful, false otherwise.
+ bool EmitWhile(const ast::WhileStatement* stmt);
+
+ /// Emits a loop control node to the IR.
+ /// @param stmt the for loop statement
+ /// @returns true if successful, false otherwise.
+ bool EmitForLoop(const ast::ForLoopStatement* stmt);
+
+ /// Emits a switch statement
+ /// @param stmt the switch statement
+ /// @returns true if successful, false otherwise.
+ bool EmitSwitch(const ast::SwitchStatement* stmt);
+
/// Emits a break statement
/// @param stmt the break statement
- /// @returns true if successfull, false otherwise.
+ /// @returns true if successful, false otherwise.
bool EmitBreak(const ast::BreakStatement* stmt);
/// Emits a continue statement
/// @param stmt the continue statement
- /// @returns true if successfull, false otherwise.
+ /// @returns true if successful, false otherwise.
bool EmitContinue(const ast::ContinueStatement* stmt);
/// Emits a break-if statement
/// @param stmt the break-if statement
- /// @returns true if successfull, false otherwise.
+ /// @returns true if successful, false otherwise.
bool EmitBreakIf(const ast::BreakIfStatement* stmt);
+ /// Emits a fallthrough statement
+ /// @returns true if successful, false otherwise
+ bool EmitFallthrough();
+
/// Retrieve the IR Flow node for a given AST node.
/// @param n the node to lookup
/// @returns the FlowNode for the given ast::Node or nullptr if it doesn't exist.
@@ -133,8 +154,8 @@
private:
enum class ControlFlags { kNone, kExcludeSwitch };
- void BranchTo(const ir::FlowNode* node);
- void BranchToIfNeeded(const ir::FlowNode* node);
+ void BranchTo(ir::FlowNode* node);
+ void BranchToIfNeeded(ir::FlowNode* node);
FlowNode* FindEnclosingControl(ControlFlags flags);
@@ -145,6 +166,9 @@
Block* current_flow_block_ = nullptr;
Function* current_function_ = nullptr;
+ // TODO(crbug.com/tint/1644): Remove this when fallthrough is removed.
+ Block* fallthrough_target_ = nullptr;
+
/// Map from ast nodes to flow nodes, used to retrieve the flow node for a given AST node.
/// Used for testing purposes.
std::unordered_map<const ast::Node*, const FlowNode*> ast_to_flow_;
diff --git a/src/tint/ir/builder_impl_test.cc b/src/tint/ir/builder_impl_test.cc
index fa37ac5..1ee66e5 100644
--- a/src/tint/ir/builder_impl_test.cc
+++ b/src/tint/ir/builder_impl_test.cc
@@ -14,9 +14,14 @@
#include "src/tint/ir/test_helper.h"
+#include "src/tint/ast/case_selector.h"
+#include "src/tint/ast/int_literal_expression.h"
+
namespace tint::ir {
namespace {
+using namespace tint::number_suffixes; // NOLINT
+
using IRBuilderImplTest = TestHelper;
TEST_F(IRBuilderImplTest, Func) {
@@ -36,6 +41,9 @@
EXPECT_NE(f->start_target, nullptr);
EXPECT_NE(f->end_target, nullptr);
+ EXPECT_EQ(1u, f->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, f->end_target->inbound_branches.Length());
+
EXPECT_EQ(f->start_target->branch_target, f->end_target);
}
@@ -82,6 +90,13 @@
ASSERT_EQ(1u, m.functions.Length());
auto* func = m.functions[0];
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(2u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
EXPECT_EQ(func->start_target->branch_target, flow);
EXPECT_EQ(flow->true_target->branch_target, flow->merge_target);
EXPECT_EQ(flow->false_target->branch_target, flow->merge_target);
@@ -116,6 +131,13 @@
ASSERT_EQ(1u, m.functions.Length());
auto* func = m.functions[0];
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
+
EXPECT_EQ(func->start_target->branch_target, flow);
EXPECT_EQ(flow->true_target->branch_target, func->end_target);
EXPECT_EQ(flow->false_target->branch_target, flow->merge_target);
@@ -150,6 +172,13 @@
ASSERT_EQ(1u, m.functions.Length());
auto* func = m.functions[0];
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
+
EXPECT_EQ(func->start_target->branch_target, flow);
EXPECT_EQ(flow->true_target->branch_target, flow->merge_target);
EXPECT_EQ(flow->false_target->branch_target, func->end_target);
@@ -179,14 +208,78 @@
auto* flow = ir_if->As<ir::If>();
ASSERT_NE(flow->true_target, nullptr);
ASSERT_NE(flow->false_target, nullptr);
+ ASSERT_NE(flow->merge_target, nullptr);
ASSERT_EQ(1u, m.functions.Length());
auto* func = m.functions[0];
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(0u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
+
EXPECT_EQ(func->start_target->branch_target, flow);
EXPECT_EQ(flow->true_target->branch_target, func->end_target);
EXPECT_EQ(flow->false_target->branch_target, func->end_target);
- EXPECT_EQ(flow->merge_target, nullptr);
+}
+
+TEST_F(IRBuilderImplTest, IfStatement_JumpChainToMerge) {
+ // if (true) {
+ // loop {
+ // break;
+ // }
+ // }
+ //
+ // func -> start -> if true
+ // -> if false
+ //
+ // [if true] -> loop
+ // [if false] -> if merge
+ // [if merge] -> func end
+ // [loop] -> loop start
+ // [loop start] -> loop merge
+ // [loop continuing] -> loop start
+ // [loop merge] -> if merge
+ //
+ auto* ast_loop = Loop(Block(Break()));
+ auto* ast_if = If(true, Block(ast_loop));
+ WrapInFunction(ast_if);
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_if = b.FlowNodeForAstNode(ast_if);
+ ASSERT_NE(ir_if, nullptr);
+ EXPECT_TRUE(ir_if->Is<ir::If>());
+
+ auto* if_flow = ir_if->As<ir::If>();
+ ASSERT_NE(if_flow->true_target, nullptr);
+ ASSERT_NE(if_flow->false_target, nullptr);
+ ASSERT_NE(if_flow->merge_target, nullptr);
+
+ auto* ir_loop = b.FlowNodeForAstNode(ast_loop);
+ ASSERT_NE(ir_loop, nullptr);
+ EXPECT_TRUE(ir_loop->Is<ir::Loop>());
+
+ auto* loop_flow = ir_loop->As<ir::Loop>();
+ ASSERT_NE(loop_flow->start_target, nullptr);
+ ASSERT_NE(loop_flow->continuing_target, nullptr);
+ ASSERT_NE(loop_flow->merge_target, nullptr);
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ EXPECT_EQ(func->start_target->branch_target, if_flow);
+ EXPECT_EQ(if_flow->true_target->branch_target, loop_flow);
+ EXPECT_EQ(loop_flow->start_target->branch_target, loop_flow->merge_target);
+ EXPECT_EQ(loop_flow->merge_target->branch_target, if_flow->merge_target);
+ EXPECT_EQ(loop_flow->continuing_target->branch_target, loop_flow->start_target);
+ EXPECT_EQ(if_flow->false_target->branch_target, if_flow->merge_target);
+ EXPECT_EQ(if_flow->merge_target->branch_target, func->end_target);
}
TEST_F(IRBuilderImplTest, Loop_WithBreak) {
@@ -214,6 +307,13 @@
ASSERT_EQ(1u, m.functions.Length());
auto* func = m.functions[0];
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(2u, flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(0u, flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
EXPECT_EQ(func->start_target->branch_target, flow);
EXPECT_EQ(flow->start_target->branch_target, flow->merge_target);
EXPECT_EQ(flow->continuing_target->branch_target, flow->start_target);
@@ -260,6 +360,17 @@
ASSERT_EQ(1u, m.functions.Length());
auto* func = m.functions[0];
+ EXPECT_EQ(1u, loop_flow->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
EXPECT_EQ(func->start_target->branch_target, loop_flow);
EXPECT_EQ(loop_flow->start_target->branch_target, if_flow);
EXPECT_EQ(if_flow->true_target->branch_target, loop_flow->merge_target);
@@ -308,6 +419,17 @@
ASSERT_EQ(1u, m.functions.Length());
auto* func = m.functions[0];
+ EXPECT_EQ(1u, loop_flow->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, break_if_flow->inbound_branches.Length());
+ EXPECT_EQ(1u, break_if_flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, break_if_flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, break_if_flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
EXPECT_EQ(func->start_target->branch_target, loop_flow);
EXPECT_EQ(loop_flow->start_target->branch_target, loop_flow->continuing_target);
EXPECT_EQ(loop_flow->continuing_target->branch_target, break_if_flow);
@@ -325,7 +447,7 @@
// [if false] -> if merge
// [if merge] -> loop continuing
// [loop continuing] -> loop start
- // [loop merge] -> func end
+ // [loop merge] -> nullptr
//
auto* ast_if = If(true, Block(Return()));
auto* ast_loop = Loop(Block(ast_if, Continue()));
@@ -357,14 +479,147 @@
ASSERT_EQ(1u, m.functions.Length());
auto* func = m.functions[0];
+ EXPECT_EQ(1u, loop_flow->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(0u, loop_flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
EXPECT_EQ(loop_flow->start_target->branch_target, if_flow);
EXPECT_EQ(if_flow->true_target->branch_target, func->end_target);
EXPECT_EQ(if_flow->false_target->branch_target, if_flow->merge_target);
-
EXPECT_EQ(loop_flow->continuing_target->branch_target, loop_flow->start_target);
EXPECT_EQ(func->start_target->branch_target, ir_loop);
- EXPECT_EQ(loop_flow->merge_target->branch_target, func->end_target);
+ EXPECT_EQ(loop_flow->merge_target->branch_target, nullptr);
+}
+
+TEST_F(IRBuilderImplTest, Loop_WithOnlyReturn) {
+ // {
+ // loop {
+ // return;
+ // continue;
+ // }
+ // if true { return; }
+ // }
+ //
+ // func -> start -> loop -> loop start -> return -> func end
+ //
+ // [loop continuing] -> loop start
+ // [loop merge] -> nullptr
+ //
+ // Note, the continue; is here is a dead call, so we won't emit a branch to the continuing block
+ // so the inbound_branches will be zero for continuing.
+ //
+ // The `if` after the `loop` is also eliminated as there is no control-flow path reaching the
+ // block.
+ auto* ast_loop = Loop(Block(Return(), Continue()));
+ WrapInFunction(ast_loop, If(true, Block(Return())));
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_loop = b.FlowNodeForAstNode(ast_loop);
+ ASSERT_NE(ir_loop, nullptr);
+ EXPECT_TRUE(ir_loop->Is<ir::Loop>());
+
+ auto* loop_flow = ir_loop->As<ir::Loop>();
+ ASSERT_NE(loop_flow->start_target, nullptr);
+ ASSERT_NE(loop_flow->continuing_target, nullptr);
+ ASSERT_NE(loop_flow->merge_target, nullptr);
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ EXPECT_EQ(1u, loop_flow->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(0u, loop_flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(0u, loop_flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
+ EXPECT_EQ(loop_flow->start_target->branch_target, func->end_target);
+ EXPECT_EQ(loop_flow->continuing_target->branch_target, loop_flow->start_target);
+
+ EXPECT_EQ(func->start_target->branch_target, ir_loop);
+}
+
+TEST_F(IRBuilderImplTest, Loop_WithOnlyReturn_ContinuingBreakIf) {
+ // {
+ // loop {
+ // return;
+ // continuing {
+ // break if true;
+ // }
+ // }
+ // if (true) { return; }
+ // }
+ //
+ // func -> start -> loop -> loop start -> return -> func end
+ //
+ // [loop continuing] -> break if true
+ // -> break if false
+ // [break if true] -> loop merge
+ // [break if false] -> if merge
+ // [break if merge] -> loop start
+ // [loop merge] -> nullptr
+ //
+ // In this case, the continuing block is dead code, but we don't really know that when parsing
+ // so we end up with a branch into the loop merge target. The loop merge can tell it's dead code
+ // so we can drop the if ater the loop.
+ auto* ast_break_if = BreakIf(true);
+ auto* ast_loop = Loop(Block(Return()), Block(ast_break_if));
+ auto* ast_if = If(true, Block(Return()));
+ WrapInFunction(Block(ast_loop, ast_if));
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_loop = b.FlowNodeForAstNode(ast_loop);
+ ASSERT_NE(ir_loop, nullptr);
+ EXPECT_TRUE(ir_loop->Is<ir::Loop>());
+
+ auto* loop_flow = ir_loop->As<ir::Loop>();
+ ASSERT_NE(loop_flow->start_target, nullptr);
+ ASSERT_NE(loop_flow->continuing_target, nullptr);
+ ASSERT_NE(loop_flow->merge_target, nullptr);
+
+ auto* ir_if = b.FlowNodeForAstNode(ast_if);
+ EXPECT_EQ(ir_if, nullptr);
+
+ auto* ir_break_if = b.FlowNodeForAstNode(ast_break_if);
+ ASSERT_NE(ir_break_if, nullptr);
+ EXPECT_TRUE(ir_break_if->Is<ir::If>());
+
+ auto* break_if_flow = ir_break_if->As<ir::If>();
+ ASSERT_NE(break_if_flow->true_target, nullptr);
+ ASSERT_NE(break_if_flow->false_target, nullptr);
+ ASSERT_NE(break_if_flow->merge_target, nullptr);
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ EXPECT_EQ(1u, loop_flow->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(0u, loop_flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ // This is 1 because only the loop branch happens. The subsequent if return is dead code.
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
+ EXPECT_EQ(loop_flow->start_target->branch_target, func->end_target);
+ EXPECT_EQ(loop_flow->continuing_target->branch_target, break_if_flow);
+
+ EXPECT_EQ(func->start_target->branch_target, ir_loop);
}
TEST_F(IRBuilderImplTest, Loop_WithIf_BothBranchesBreak) {
@@ -402,10 +657,22 @@
auto* if_flow = ir_if->As<ir::If>();
ASSERT_NE(if_flow->true_target, nullptr);
ASSERT_NE(if_flow->false_target, nullptr);
+ ASSERT_NE(if_flow->merge_target, nullptr);
ASSERT_EQ(1u, m.functions.Length());
auto* func = m.functions[0];
+ EXPECT_EQ(1u, loop_flow->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(0u, loop_flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(0u, if_flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
// Note, the `continue` is dead code because both if branches go out of loop, so it just gets
// dropped.
@@ -413,7 +680,6 @@
EXPECT_EQ(loop_flow->start_target->branch_target, if_flow);
EXPECT_EQ(if_flow->true_target->branch_target, loop_flow->merge_target);
EXPECT_EQ(if_flow->false_target->branch_target, loop_flow->merge_target);
- EXPECT_EQ(if_flow->merge_target, nullptr);
EXPECT_EQ(loop_flow->continuing_target->branch_target, loop_flow->start_target);
EXPECT_EQ(loop_flow->merge_target->branch_target, func->end_target);
}
@@ -551,6 +817,41 @@
ASSERT_EQ(1u, m.functions.Length());
auto* func = m.functions[0];
+ EXPECT_EQ(1u, loop_flow_a->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow_a->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow_a->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow_a->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow_b->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow_b->start_target->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow_b->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow_b->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow_c->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow_c->start_target->inbound_branches.Length());
+ EXPECT_EQ(0u, loop_flow_c->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow_c->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow_d->inbound_branches.Length());
+ EXPECT_EQ(2u, loop_flow_d->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow_d->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, loop_flow_d->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_a->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_a->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_a->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_a->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_b->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_b->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_b->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_b->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_c->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_c->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_c->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_c->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_d->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_d->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_d->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow_d->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
EXPECT_EQ(func->start_target->branch_target, loop_flow_a);
EXPECT_EQ(loop_flow_a->start_target->branch_target, loop_flow_b);
EXPECT_EQ(loop_flow_b->start_target->branch_target, if_flow_a);
@@ -578,5 +879,498 @@
EXPECT_EQ(loop_flow_a->merge_target->branch_target, func->end_target);
}
+TEST_F(IRBuilderImplTest, While) {
+ // {
+ // while false {
+ // }
+ // }
+ //
+ // func -> while -> loop_start -> if true
+ // -> if false
+ //
+ // [if true] -> if merge
+ // [if false] -> while merge
+ // [if merge] -> loop continuing
+ // [loop continuing] -> loop start
+ // [while merge] -> func end
+ //
+ auto* ast_while = While(false, Block());
+ WrapInFunction(ast_while);
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_while = b.FlowNodeForAstNode(ast_while);
+ ASSERT_NE(ir_while, nullptr);
+ ASSERT_TRUE(ir_while->Is<ir::Loop>());
+
+ auto* flow = ir_while->As<ir::Loop>();
+ ASSERT_NE(flow->start_target, nullptr);
+ ASSERT_NE(flow->continuing_target, nullptr);
+ ASSERT_NE(flow->merge_target, nullptr);
+
+ ASSERT_NE(flow->start_target->branch_target, nullptr);
+ ASSERT_TRUE(flow->start_target->branch_target->Is<ir::If>());
+ auto* if_flow = flow->start_target->branch_target->As<ir::If>();
+ ASSERT_NE(if_flow->true_target, nullptr);
+ ASSERT_NE(if_flow->false_target, nullptr);
+ ASSERT_NE(if_flow->merge_target, nullptr);
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(2u, flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->merge_target->inbound_branches.Length());
+
+ EXPECT_EQ(func->start_target->branch_target, flow);
+ EXPECT_EQ(flow->start_target->branch_target, if_flow);
+ EXPECT_EQ(if_flow->true_target->branch_target, if_flow->merge_target);
+ EXPECT_EQ(if_flow->false_target->branch_target, flow->merge_target);
+ EXPECT_EQ(if_flow->merge_target->branch_target, flow->continuing_target);
+ EXPECT_EQ(flow->continuing_target->branch_target, flow->start_target);
+ EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
+}
+
+TEST_F(IRBuilderImplTest, While_Return) {
+ // {
+ // while true {
+ // return;
+ // }
+ // }
+ //
+ // func -> while -> if true
+ // if false
+ //
+ // [if true] -> if merge
+ // [if false] -> while merge
+ // [if merge] -> func end
+ // [while merge] -> func end
+ //
+ auto* ast_while = While(true, Block(Return()));
+ WrapInFunction(ast_while);
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_while = b.FlowNodeForAstNode(ast_while);
+ ASSERT_NE(ir_while, nullptr);
+ ASSERT_TRUE(ir_while->Is<ir::Loop>());
+
+ auto* flow = ir_while->As<ir::Loop>();
+ ASSERT_NE(flow->start_target, nullptr);
+ ASSERT_NE(flow->continuing_target, nullptr);
+ ASSERT_NE(flow->merge_target, nullptr);
+
+ ASSERT_NE(flow->start_target->branch_target, nullptr);
+ ASSERT_TRUE(flow->start_target->branch_target->Is<ir::If>());
+ auto* if_flow = flow->start_target->branch_target->As<ir::If>();
+ ASSERT_NE(if_flow->true_target, nullptr);
+ ASSERT_NE(if_flow->false_target, nullptr);
+ ASSERT_NE(if_flow->merge_target, nullptr);
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(2u, flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(0u, flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->merge_target->inbound_branches.Length());
+
+ EXPECT_EQ(func->start_target->branch_target, flow);
+ EXPECT_EQ(flow->start_target->branch_target, if_flow);
+ EXPECT_EQ(if_flow->true_target->branch_target, if_flow->merge_target);
+ EXPECT_EQ(if_flow->false_target->branch_target, flow->merge_target);
+ EXPECT_EQ(if_flow->merge_target->branch_target, func->end_target);
+ EXPECT_EQ(flow->continuing_target->branch_target, flow->start_target);
+ EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
+}
+
+// TODO(dsinclair): Enable when variable declarations and increment are supported
+TEST_F(IRBuilderImplTest, DISABLED_For) {
+ // for(var i: 0; i < 10; i++) {
+ // }
+ //
+ // func -> loop -> loop start -> if true
+ // -> if false
+ //
+ // [if true] -> if merge
+ // [if false] -> loop merge
+ // [if merge] -> loop continuing
+ // [loop continuing] -> loop start
+ // [loop merge] -> func end
+ //
+ auto* ast_for = For(Decl(Var("i", ty.i32())), LessThan("i", 10_a), Increment("i"), Block());
+ WrapInFunction(ast_for);
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_for = b.FlowNodeForAstNode(ast_for);
+ ASSERT_NE(ir_for, nullptr);
+ ASSERT_TRUE(ir_for->Is<ir::Loop>());
+
+ auto* flow = ir_for->As<ir::Loop>();
+ ASSERT_NE(flow->start_target, nullptr);
+ ASSERT_NE(flow->continuing_target, nullptr);
+ ASSERT_NE(flow->merge_target, nullptr);
+
+ ASSERT_NE(flow->start_target->branch_target, nullptr);
+ ASSERT_TRUE(flow->start_target->branch_target->Is<ir::If>());
+ auto* if_flow = flow->start_target->branch_target->As<ir::If>();
+ ASSERT_NE(if_flow->true_target, nullptr);
+ ASSERT_NE(if_flow->false_target, nullptr);
+ ASSERT_NE(if_flow->merge_target, nullptr);
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(2u, flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->true_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->false_target->inbound_branches.Length());
+ EXPECT_EQ(1u, if_flow->merge_target->inbound_branches.Length());
+
+ EXPECT_EQ(func->start_target->branch_target, flow);
+ EXPECT_EQ(flow->start_target->branch_target, if_flow);
+ EXPECT_EQ(if_flow->true_target->branch_target, if_flow->merge_target);
+ EXPECT_EQ(if_flow->false_target->branch_target, flow->merge_target);
+ EXPECT_EQ(if_flow->merge_target->branch_target, flow->continuing_target);
+ EXPECT_EQ(flow->continuing_target->branch_target, flow->start_target);
+ EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
+}
+
+TEST_F(IRBuilderImplTest, For_NoInitCondOrContinuing) {
+ // for (;;) {
+ // break;
+ // }
+ //
+ // func -> loop -> loop start -> loop merge -> func end
+ //
+ auto* ast_for = For(nullptr, nullptr, nullptr, Block(Break()));
+ WrapInFunction(ast_for);
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_for = b.FlowNodeForAstNode(ast_for);
+ ASSERT_NE(ir_for, nullptr);
+ ASSERT_TRUE(ir_for->Is<ir::Loop>());
+
+ auto* flow = ir_for->As<ir::Loop>();
+ ASSERT_NE(flow->start_target, nullptr);
+ ASSERT_NE(flow->continuing_target, nullptr);
+ ASSERT_NE(flow->merge_target, nullptr);
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(2u, flow->start_target->inbound_branches.Length());
+ EXPECT_EQ(0u, flow->continuing_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
+ EXPECT_EQ(flow->start_target->branch_target, flow->merge_target);
+ EXPECT_EQ(flow->continuing_target->branch_target, flow->start_target);
+ EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
+}
+
+TEST_F(IRBuilderImplTest, Switch) {
+ // func -> switch -> case 1
+ // -> case 2
+ // -> default
+ //
+ // [case 1] -> switch merge
+ // [case 2] -> switch merge
+ // [default] -> switch merge
+ // [switch merge] -> func end
+ //
+ auto* ast_switch = Switch(
+ 1_i, utils::Vector{Case(utils::Vector{CaseSelector(0_i)}, Block()),
+ Case(utils::Vector{CaseSelector(1_i)}, Block()), DefaultCase(Block())});
+
+ WrapInFunction(ast_switch);
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_switch = b.FlowNodeForAstNode(ast_switch);
+ ASSERT_NE(ir_switch, nullptr);
+ ASSERT_TRUE(ir_switch->Is<ir::Switch>());
+
+ auto* flow = ir_switch->As<ir::Switch>();
+ ASSERT_NE(flow->merge_target, nullptr);
+ ASSERT_EQ(3u, flow->cases.Length());
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ ASSERT_EQ(1u, flow->cases[0].selectors.Length());
+ ASSERT_TRUE(flow->cases[0].selectors[0]->expr->Is<ast::IntLiteralExpression>());
+ EXPECT_EQ(0_i, flow->cases[0].selectors[0]->expr->As<ast::IntLiteralExpression>()->value);
+
+ ASSERT_EQ(1u, flow->cases[1].selectors.Length());
+ ASSERT_TRUE(flow->cases[1].selectors[0]->expr->Is<ast::IntLiteralExpression>());
+ EXPECT_EQ(1_i, flow->cases[1].selectors[0]->expr->As<ast::IntLiteralExpression>()->value);
+
+ ASSERT_EQ(1u, flow->cases[2].selectors.Length());
+ EXPECT_TRUE(flow->cases[2].selectors[0]->IsDefault());
+
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->cases[0].start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->cases[1].start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->cases[2].start_target->inbound_branches.Length());
+ EXPECT_EQ(3u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
+ EXPECT_EQ(func->start_target->branch_target, ir_switch);
+ EXPECT_EQ(flow->cases[0].start_target->branch_target, flow->merge_target);
+ EXPECT_EQ(flow->cases[1].start_target->branch_target, flow->merge_target);
+ EXPECT_EQ(flow->cases[2].start_target->branch_target, flow->merge_target);
+ EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
+}
+
+TEST_F(IRBuilderImplTest, Switch_OnlyDefault) {
+ // func -> switch -> default -> switch merge -> func end
+ //
+ auto* ast_switch = Switch(1_i, utils::Vector{DefaultCase(Block())});
+
+ WrapInFunction(ast_switch);
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_switch = b.FlowNodeForAstNode(ast_switch);
+ ASSERT_NE(ir_switch, nullptr);
+ ASSERT_TRUE(ir_switch->Is<ir::Switch>());
+
+ auto* flow = ir_switch->As<ir::Switch>();
+ ASSERT_NE(flow->merge_target, nullptr);
+ ASSERT_EQ(1u, flow->cases.Length());
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ ASSERT_EQ(1u, flow->cases[0].selectors.Length());
+ EXPECT_TRUE(flow->cases[0].selectors[0]->IsDefault());
+
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->cases[0].start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
+ EXPECT_EQ(func->start_target->branch_target, ir_switch);
+ EXPECT_EQ(flow->cases[0].start_target->branch_target, flow->merge_target);
+ EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
+}
+
+TEST_F(IRBuilderImplTest, Switch_WithBreak) {
+ // {
+ // switch(1) {
+ // case 0: {
+ // break;
+ // if true { return;} // Dead code
+ // }
+ // default: {}
+ // }
+ // }
+ //
+ // func -> switch -> case 1
+ // -> default
+ //
+ // [case 1] -> switch merge
+ // [default] -> switch merge
+ // [switch merge] -> func end
+ auto* ast_switch = Switch(1_i, utils::Vector{Case(utils::Vector{CaseSelector(0_i)},
+ Block(Break(), If(true, Block(Return())))),
+ DefaultCase(Block())});
+
+ WrapInFunction(ast_switch);
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_switch = b.FlowNodeForAstNode(ast_switch);
+ ASSERT_NE(ir_switch, nullptr);
+ ASSERT_TRUE(ir_switch->Is<ir::Switch>());
+
+ auto* flow = ir_switch->As<ir::Switch>();
+ ASSERT_NE(flow->merge_target, nullptr);
+ ASSERT_EQ(2u, flow->cases.Length());
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ ASSERT_EQ(1u, flow->cases[0].selectors.Length());
+ ASSERT_TRUE(flow->cases[0].selectors[0]->expr->Is<ast::IntLiteralExpression>());
+ EXPECT_EQ(0_i, flow->cases[0].selectors[0]->expr->As<ast::IntLiteralExpression>()->value);
+
+ ASSERT_EQ(1u, flow->cases[1].selectors.Length());
+ EXPECT_TRUE(flow->cases[1].selectors[0]->IsDefault());
+
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->cases[0].start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->cases[1].start_target->inbound_branches.Length());
+ EXPECT_EQ(2u, flow->merge_target->inbound_branches.Length());
+ // This is 1 because the if is dead-code eliminated and the return doesn't happen.
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
+ EXPECT_EQ(func->start_target->branch_target, ir_switch);
+ EXPECT_EQ(flow->cases[0].start_target->branch_target, flow->merge_target);
+ EXPECT_EQ(flow->cases[1].start_target->branch_target, flow->merge_target);
+ EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
+}
+
+TEST_F(IRBuilderImplTest, Switch_AllReturn) {
+ // {
+ // switch(1) {
+ // case 0: {
+ // return;
+ // }
+ // default: {
+ // return;
+ // }
+ // }
+ // if true { return; } // Dead code
+ // }
+ //
+ // func -> switch -> case 1
+ // -> default
+ //
+ // [case 1] -> func end
+ // [default] -> func end
+ // [switch merge] -> nullptr
+ //
+ auto* ast_switch =
+ Switch(1_i, utils::Vector{Case(utils::Vector{CaseSelector(0_i)}, Block(Return())),
+ DefaultCase(Block(Return()))});
+
+ auto* ast_if = If(true, Block(Return()));
+
+ WrapInFunction(ast_switch, ast_if);
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ ASSERT_EQ(b.FlowNodeForAstNode(ast_if), nullptr);
+
+ auto* ir_switch = b.FlowNodeForAstNode(ast_switch);
+ ASSERT_NE(ir_switch, nullptr);
+ ASSERT_TRUE(ir_switch->Is<ir::Switch>());
+
+ auto* flow = ir_switch->As<ir::Switch>();
+ ASSERT_NE(flow->merge_target, nullptr);
+ ASSERT_EQ(2u, flow->cases.Length());
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ ASSERT_EQ(1u, flow->cases[0].selectors.Length());
+ ASSERT_TRUE(flow->cases[0].selectors[0]->expr->Is<ast::IntLiteralExpression>());
+ EXPECT_EQ(0_i, flow->cases[0].selectors[0]->expr->As<ast::IntLiteralExpression>()->value);
+
+ ASSERT_EQ(1u, flow->cases[1].selectors.Length());
+ EXPECT_TRUE(flow->cases[1].selectors[0]->IsDefault());
+
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->cases[0].start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->cases[1].start_target->inbound_branches.Length());
+ EXPECT_EQ(0u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
+
+ EXPECT_EQ(func->start_target->branch_target, ir_switch);
+ EXPECT_EQ(flow->cases[0].start_target->branch_target, func->end_target);
+ EXPECT_EQ(flow->cases[1].start_target->branch_target, func->end_target);
+ EXPECT_EQ(flow->merge_target->branch_target, nullptr);
+}
+
+// TODO(crbug.com/tint/1644): Remove when fallthrough is removed.
+TEST_F(IRBuilderImplTest, Switch_Fallthrough) {
+ // func -> switch -> case 1
+ // -> case 2
+ // -> default
+ //
+ // [case 1] -> switch merge
+ // [case 2] -> default
+ // [default] -> switch merge
+ // [switch merge] -> func end
+ //
+ auto* ast_switch =
+ Switch(1_i, utils::Vector{Case(utils::Vector{CaseSelector(0_i)}, Block()),
+ Case(utils::Vector{CaseSelector(1_i)}, Block(Fallthrough())),
+ DefaultCase(Block())});
+
+ WrapInFunction(ast_switch);
+ auto& b = Build();
+
+ auto r = b.Build();
+ ASSERT_TRUE(r) << b.error();
+ auto m = r.Move();
+
+ auto* ir_switch = b.FlowNodeForAstNode(ast_switch);
+ ASSERT_NE(ir_switch, nullptr);
+ ASSERT_TRUE(ir_switch->Is<ir::Switch>());
+
+ auto* flow = ir_switch->As<ir::Switch>();
+ ASSERT_NE(flow->merge_target, nullptr);
+ ASSERT_EQ(3u, flow->cases.Length());
+
+ ASSERT_EQ(1u, m.functions.Length());
+ auto* func = m.functions[0];
+
+ ASSERT_EQ(1u, flow->cases[0].selectors.Length());
+ ASSERT_TRUE(flow->cases[0].selectors[0]->expr->Is<ast::IntLiteralExpression>());
+ EXPECT_EQ(0_i, flow->cases[0].selectors[0]->expr->As<ast::IntLiteralExpression>()->value);
+
+ ASSERT_EQ(1u, flow->cases[1].selectors.Length());
+ ASSERT_TRUE(flow->cases[1].selectors[0]->expr->Is<ast::IntLiteralExpression>());
+ EXPECT_EQ(1_i, flow->cases[1].selectors[0]->expr->As<ast::IntLiteralExpression>()->value);
+
+ ASSERT_EQ(1u, flow->cases[2].selectors.Length());
+ EXPECT_TRUE(flow->cases[2].selectors[0]->IsDefault());
+
+ EXPECT_EQ(1u, flow->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->cases[0].start_target->inbound_branches.Length());
+ EXPECT_EQ(1u, flow->cases[1].start_target->inbound_branches.Length());
+ EXPECT_EQ(2u, flow->cases[2].start_target->inbound_branches.Length());
+ EXPECT_EQ(2u, flow->merge_target->inbound_branches.Length());
+ EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
+
+ EXPECT_EQ(func->start_target->branch_target, ir_switch);
+ EXPECT_EQ(flow->cases[0].start_target->branch_target, flow->merge_target);
+ EXPECT_EQ(flow->cases[1].start_target->branch_target, flow->cases[2].start_target);
+ EXPECT_EQ(flow->cases[2].start_target->branch_target, flow->merge_target);
+ EXPECT_EQ(flow->merge_target->branch_target, func->end_target);
+}
+
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/debug.cc b/src/tint/ir/debug.cc
new file mode 100644
index 0000000..be83111
--- /dev/null
+++ b/src/tint/ir/debug.cc
@@ -0,0 +1,159 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/ir/debug.h"
+
+#include <sstream>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "src/tint/ir/block.h"
+#include "src/tint/ir/if.h"
+#include "src/tint/ir/loop.h"
+#include "src/tint/ir/switch.h"
+#include "src/tint/ir/terminator.h"
+#include "src/tint/program.h"
+
+namespace tint::ir {
+
+// static
+std::string Debug::AsDotGraph(const Module* mod) {
+ size_t node_count = 0;
+
+ std::unordered_set<const FlowNode*> visited;
+ std::unordered_set<const FlowNode*> merge_nodes;
+ std::unordered_map<const FlowNode*, std::string> node_to_name;
+ std::stringstream out;
+
+ auto name_for = [&](const FlowNode* node) -> std::string {
+ if (node_to_name.count(node) > 0) {
+ return node_to_name[node];
+ }
+
+ std::string name = "node_" + std::to_string(node_count);
+ node_count += 1;
+
+ node_to_name[node] = name;
+ return name;
+ };
+
+ std::function<void(const FlowNode*)> Graph = [&](const FlowNode* node) {
+ if (visited.count(node) > 0) {
+ return;
+ }
+ visited.insert(node);
+
+ tint::Switch(
+ node,
+ [&](const ir::Block* b) {
+ if (node_to_name.count(b) == 0) {
+ out << name_for(b) << R"( [label="block"])" << std::endl;
+ }
+ out << name_for(b) << " -> " << name_for(b->branch_target);
+
+ // Dashed lines to merge blocks
+ if (merge_nodes.count(b->branch_target) != 0) {
+ out << " [style=dashed]";
+ }
+
+ out << std::endl;
+ Graph(b->branch_target);
+ },
+ [&](const ir::Switch* s) {
+ out << name_for(s) << R"( [label="switch"])" << std::endl;
+ out << name_for(s->merge_target) << R"( [label="switch merge"])" << std::endl;
+ merge_nodes.insert(s->merge_target);
+
+ size_t i = 0;
+ for (const auto& c : s->cases) {
+ out << name_for(c.start_target)
+ << R"( [label="case )" + std::to_string(i++) + R"("])" << std::endl;
+ }
+ out << name_for(s) << " -> {";
+ for (const auto& c : s->cases) {
+ if (&c != &(s->cases[0])) {
+ out << ", ";
+ }
+ out << name_for(c.start_target);
+ }
+ out << "}" << std::endl;
+
+ for (const auto& c : s->cases) {
+ Graph(c.start_target);
+ }
+ Graph(s->merge_target);
+ },
+ [&](const ir::If* i) {
+ out << name_for(i) << R"( [label="if"])" << std::endl;
+ out << name_for(i->true_target) << R"( [label="true"])" << std::endl;
+ out << name_for(i->false_target) << R"( [label="false"])" << std::endl;
+ out << name_for(i->merge_target) << R"( [label="if merge"])" << std::endl;
+ merge_nodes.insert(i->merge_target);
+
+ out << name_for(i) << " -> {";
+ out << name_for(i->true_target) << ", " << name_for(i->false_target);
+ out << "}" << std::endl;
+
+ // Subgraph if true/false branches so they draw on the same line
+ out << "subgraph sub_" << name_for(i) << " {" << std::endl;
+ out << R"(rank="same")" << std::endl;
+ out << name_for(i->true_target) << std::endl;
+ out << name_for(i->false_target) << std::endl;
+ out << "}" << std::endl;
+
+ Graph(i->true_target);
+ Graph(i->false_target);
+ Graph(i->merge_target);
+ },
+ [&](const ir::Loop* l) {
+ out << name_for(l) << R"( [label="loop"])" << std::endl;
+ out << name_for(l->start_target) << R"( [label="start"])" << std::endl;
+ out << name_for(l->continuing_target) << R"( [label="continuing"])" << std::endl;
+ out << name_for(l->merge_target) << R"( [label="loop merge"])" << std::endl;
+ merge_nodes.insert(l->merge_target);
+
+ // Subgraph the continuing and merge so they get drawn on the same line
+ out << "subgraph sub_" << name_for(l) << " {" << std::endl;
+ out << R"(rank="same")" << std::endl;
+ out << name_for(l->continuing_target) << std::endl;
+ out << name_for(l->merge_target) << std::endl;
+ out << "}" << std::endl;
+
+ out << name_for(l) << " -> " << name_for(l->start_target) << std::endl;
+
+ Graph(l->start_target);
+ Graph(l->continuing_target);
+ Graph(l->merge_target);
+ },
+ [&](const ir::Terminator*) {
+ // Already done
+ });
+ };
+
+ out << "digraph G {" << std::endl;
+ for (const auto* func : mod->functions) {
+ // Cluster each function to label and draw a box around it.
+ out << "subgraph cluster_" << name_for(func) << " {" << std::endl;
+ out << R"(label=")" << mod->program->Symbols().NameFor(func->source->symbol) << R"(")"
+ << std::endl;
+ out << name_for(func->start_target) << R"( [label="start"])" << std::endl;
+ out << name_for(func->end_target) << R"( [label="end"])" << std::endl;
+ Graph(func->start_target);
+ out << "}" << std::endl;
+ }
+ out << "}";
+ return out.str();
+}
+
+} // namespace tint::ir
diff --git a/src/tint/ir/debug.h b/src/tint/ir/debug.h
new file mode 100644
index 0000000..bd0570b
--- /dev/null
+++ b/src/tint/ir/debug.h
@@ -0,0 +1,35 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_IR_DEBUG_H_
+#define SRC_TINT_IR_DEBUG_H_
+
+#include <string>
+
+#include "src/tint/ir/module.h"
+
+namespace tint::ir {
+
+/// Helper class to debug IR.
+class Debug {
+ public:
+ /// Returns the module as a dot graph
+ /// @param mod the module to emit
+ /// @returns the dot graph for the given module
+ static std::string AsDotGraph(const Module* mod);
+};
+
+} // namespace tint::ir
+
+#endif // SRC_TINT_IR_DEBUG_H_
diff --git a/src/tint/ir/flow_node.h b/src/tint/ir/flow_node.h
index 0158af4..2b5ec39 100644
--- a/src/tint/ir/flow_node.h
+++ b/src/tint/ir/flow_node.h
@@ -16,6 +16,7 @@
#define SRC_TINT_IR_FLOW_NODE_H_
#include "src/tint/castable.h"
+#include "src/tint/utils/vector.h"
namespace tint::ir {
@@ -24,6 +25,13 @@
public:
~FlowNode() override;
+ /// The list of flow nodes which branch into this node. This list maybe empty for several
+ /// reasons:
+ /// - Node is a start node
+ /// - Node is a merge target outside control flow (if that returns in both branches)
+ /// - Node is a continue target outside control flow (loop that returns)
+ utils::Vector<FlowNode*, 2> inbound_branches;
+
protected:
/// Constructor
FlowNode();
diff --git a/src/tint/ir/if.h b/src/tint/ir/if.h
index 84967b0..2d28aa1 100644
--- a/src/tint/ir/if.h
+++ b/src/tint/ir/if.h
@@ -25,8 +25,7 @@
namespace tint::ir {
-/// A flow node representing an if statement. The node always contains a true and a false block. It
-/// may contain a merge block where the true/false blocks will merge too unless they return.
+/// A flow node representing an if statement.
class If : public Castable<If, FlowNode> {
public:
/// Constructor
@@ -41,7 +40,8 @@
Block* true_target = nullptr;
/// The false branch block
Block* false_target = nullptr;
- /// An optional block where the true/false blocks will branch too if needed.
+ /// An block to reconvert the true/false barnches. The block always exists, but there maybe no
+ /// branches into it. (e.g. if both branches `return`)
Block* merge_target = nullptr;
};
diff --git a/src/tint/ir/loop.cc b/src/tint/ir/loop.cc
index 4458de6..46ac5a1 100644
--- a/src/tint/ir/loop.cc
+++ b/src/tint/ir/loop.cc
@@ -14,11 +14,17 @@
#include "src/tint/ir/loop.h"
+#include "src/tint/ast/for_loop_statement.h"
+#include "src/tint/ast/loop_statement.h"
+#include "src/tint/ast/while_statement.h"
+
TINT_INSTANTIATE_TYPEINFO(tint::ir::Loop);
namespace tint::ir {
-Loop::Loop(const ast::LoopStatement* stmt) : Base(), source(stmt) {}
+Loop::Loop(const ast::Statement* s) : Base(), source(s) {
+ TINT_ASSERT(IR, (s->IsAnyOf<ast::LoopStatement, ast::WhileStatement, ast::ForLoopStatement>()));
+}
Loop::~Loop() = default;
diff --git a/src/tint/ir/loop.h b/src/tint/ir/loop.h
index 03a0190..52d24fb 100644
--- a/src/tint/ir/loop.h
+++ b/src/tint/ir/loop.h
@@ -15,7 +15,7 @@
#ifndef SRC_TINT_IR_LOOP_H_
#define SRC_TINT_IR_LOOP_H_
-#include "src/tint/ast/loop_statement.h"
+#include "src/tint/ast/statement.h"
#include "src/tint/ir/block.h"
#include "src/tint/ir/flow_node.h"
@@ -25,12 +25,12 @@
class Loop : public Castable<Loop, FlowNode> {
public:
/// Constructor
- /// @param stmt the ast::LoopStatement
- explicit Loop(const ast::LoopStatement* stmt);
+ /// @param stmt the loop, while or for statement.
+ explicit Loop(const ast::Statement* stmt);
~Loop() override;
- /// The ast loop statement this ir loop is created from.
- const ast::LoopStatement* source;
+ /// The ast loop, while or for statement this ir loop is created from.
+ const ast::Statement* source;
/// The start block is the first block in a loop.
Block* start_target = nullptr;
diff --git a/src/tint/ir/switch.cc b/src/tint/ir/switch.cc
index 9ad6d30..23b7fbb 100644
--- a/src/tint/ir/switch.cc
+++ b/src/tint/ir/switch.cc
@@ -18,7 +18,7 @@
namespace tint::ir {
-Switch::Switch() : Base() {}
+Switch::Switch(const ast::SwitchStatement* stmt) : Base(), source(stmt) {}
Switch::~Switch() = default;
diff --git a/src/tint/ir/switch.h b/src/tint/ir/switch.h
index e9de3ae..39d3d06 100644
--- a/src/tint/ir/switch.h
+++ b/src/tint/ir/switch.h
@@ -18,17 +18,38 @@
#include "src/tint/ir/block.h"
#include "src/tint/ir/flow_node.h"
+// Forward declarations
+namespace tint::ast {
+class CaseSelector;
+class SwitchStatement;
+} // namespace tint::ast
+
namespace tint::ir {
/// Flow node representing a switch statement
class Switch : public Castable<Switch, FlowNode> {
public:
+ /// A case label in the struct
+ struct Case {
+ /// The case selector for this node
+ const utils::VectorRef<const ast::CaseSelector*> selectors;
+ /// The start block for the case block.
+ Block* start_target;
+ };
+
/// Constructor
- Switch();
+ /// @param stmt the originating ast switch statement
+ explicit Switch(const ast::SwitchStatement* stmt);
~Switch() override;
+ /// The originating switch statment in the AST
+ const ast::SwitchStatement* source;
+
/// The switch merge target
Block* merge_target;
+
+ /// The switch case statements
+ utils::Vector<Case, 4> cases;
};
} // namespace tint::ir
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index 25e6214..2f5b5e0 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -109,7 +109,7 @@
#include "src/tint/sem/vector.h"
#include "src/tint/sem/void.h"
-#ifdef INCLUDE_TINT_TINT_H_
+#ifdef CURRENTLY_IN_TINT_PUBLIC_HEADER
#error "internal tint header being #included from tint.h"
#endif
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index 4c71607..d3febf2 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -3419,7 +3419,7 @@
utils::Hashmap<uint32_t, Symbol, 8> copied_phis;
for (const auto assignment : worklist) {
const auto phi_id = assignment.phi_id;
- if (read_set.Find(phi_id)) {
+ if (read_set.Contains(phi_id)) {
auto copy_name = namer_.MakeDerivedName(namer_.Name(phi_id) + "_c" +
std::to_string(block_info.id));
auto copy_sym = builder_.Symbols().Register(copy_name);
diff --git a/src/tint/reader/spirv/function_conversion_test.cc b/src/tint/reader/spirv/function_conversion_test.cc
index eab0031..1b28190 100644
--- a/src/tint/reader/spirv/function_conversion_test.cc
+++ b/src/tint/reader/spirv/function_conversion_test.cc
@@ -615,7 +615,6 @@
// TODO(dneto): OpSConvert // only if multiple widths
// TODO(dneto): OpUConvert // only if multiple widths
// TODO(dneto): OpFConvert // only if multiple widths
-// TODO(dneto): OpQuantizeToF16 // only if f16 supported
// TODO(dneto): OpSatConvertSToU // Kernel (OpenCL), not in WebGPU
// TODO(dneto): OpSatConvertUToS // Kernel (OpenCL), not in WebGPU
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index 62352ee..976706a 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -154,21 +154,26 @@
/// Constructor that starts with the input `start` Source
/// @param parser the parser
/// @param start the start source of the range
- MultiTokenSource(ParserImpl* parser, const Source& start) : parser_(parser), start_(start) {}
+ MultiTokenSource(ParserImpl* parser, const tint::Source& start)
+ : parser_(parser), start_(start) {}
- /// Implicit conversion to Source that returns the combined source from start
- /// to the current last token's source.
- operator Source() const {
- Source end = parser_->last_source().End();
+ /// @returns the Source that returns the combined source from start to the current last token's
+ /// source.
+ tint::Source Source() const {
+ auto end = parser_->last_source().End();
if (end < start_) {
end = start_;
}
return Source::Combine(start_, end);
}
+ /// Implicit conversion to Source that returns the combined source from start to the current
+ /// last token's source.
+ operator tint::Source() const { return Source(); }
+
private:
ParserImpl* parser_;
- Source start_;
+ tint::Source start_;
};
ParserImpl::TypedIdentifier::TypedIdentifier() = default;
@@ -1901,12 +1906,15 @@
// | LET optionally_typed_ident EQUAL expression
// | CONST optionally_typed_ident EQUAL expression
Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_statement() {
+ auto decl_source_range = make_source_range();
if (match(Token::Type::kConst)) {
- auto decl = expect_optionally_typed_ident("'const' declaration");
- if (decl.errored) {
+ auto typed_ident = expect_optionally_typed_ident("'const' declaration");
+ if (typed_ident.errored) {
return Failure::kErrored;
}
+ auto decl_source = decl_source_range.Source();
+
if (!expect("'const' declaration", Token::Type::kEqual)) {
return Failure::kErrored;
}
@@ -1919,21 +1927,23 @@
return add_error(peek(), "missing initializer for 'const' declaration");
}
- auto* const_ = create<ast::Const>(decl->source, // source
- builder_.Symbols().Register(decl->name), // symbol
- decl->type, // type
- initializer.value, // initializer
- utils::Empty); // attributes
+ auto* const_ = create<ast::Const>(typed_ident->source, // source
+ builder_.Symbols().Register(typed_ident->name), // symbol
+ typed_ident->type, // type
+ initializer.value, // initializer
+ utils::Empty); // attributes
- return create<ast::VariableDeclStatement>(decl->source, const_);
+ return create<ast::VariableDeclStatement>(decl_source, const_);
}
if (match(Token::Type::kLet)) {
- auto decl = expect_optionally_typed_ident("'let' declaration");
- if (decl.errored) {
+ auto typed_ident = expect_optionally_typed_ident("'let' declaration");
+ if (typed_ident.errored) {
return Failure::kErrored;
}
+ auto decl_source = decl_source_range.Source();
+
if (!expect("'let' declaration", Token::Type::kEqual)) {
return Failure::kErrored;
}
@@ -1946,13 +1956,13 @@
return add_error(peek(), "missing initializer for 'let' declaration");
}
- auto* let = create<ast::Let>(decl->source, // source
- builder_.Symbols().Register(decl->name), // symbol
- decl->type, // type
- initializer.value, // initializer
- utils::Empty); // attributes
+ auto* let = create<ast::Let>(typed_ident->source, // source
+ builder_.Symbols().Register(typed_ident->name), // symbol
+ typed_ident->type, // type
+ initializer.value, // initializer
+ utils::Empty); // attributes
- return create<ast::VariableDeclStatement>(decl->source, let);
+ return create<ast::VariableDeclStatement>(decl_source, let);
}
auto decl = variable_decl();
@@ -1963,6 +1973,8 @@
return Failure::kNoMatch;
}
+ auto decl_source = decl_source_range.Source();
+
const ast::Expression* initializer = nullptr;
if (match(Token::Type::kEqual)) {
auto initializer_expr = expression();
@@ -1976,7 +1988,7 @@
initializer = initializer_expr.value;
}
- auto* var = create<ast::Var>(decl->source, // source
+ auto* var = create<ast::Var>(decl_source, // source
builder_.Symbols().Register(decl->name), // symbol
decl->type, // type
decl->address_space, // address space
diff --git a/src/tint/reader/wgsl/parser_impl_variable_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_variable_stmt_test.cc
index 703eb57..05f2976 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_stmt_test.cc
@@ -28,10 +28,10 @@
ASSERT_NE(e->variable, nullptr);
EXPECT_EQ(e->variable->symbol, p->builder().Symbols().Get("a"));
- ASSERT_EQ(e->source.range.begin.line, 1u);
- ASSERT_EQ(e->source.range.begin.column, 5u);
- ASSERT_EQ(e->source.range.end.line, 1u);
- ASSERT_EQ(e->source.range.end.column, 6u);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 1u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 12u);
EXPECT_EQ(e->variable->initializer, nullptr);
}
@@ -47,10 +47,10 @@
ASSERT_NE(e->variable, nullptr);
EXPECT_EQ(e->variable->symbol, p->builder().Symbols().Get("a"));
- ASSERT_EQ(e->source.range.begin.line, 1u);
- ASSERT_EQ(e->source.range.begin.column, 5u);
- ASSERT_EQ(e->source.range.end.line, 1u);
- ASSERT_EQ(e->source.range.end.column, 6u);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 1u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 12u);
ASSERT_NE(e->variable->initializer, nullptr);
EXPECT_TRUE(e->variable->initializer->Is<ast::LiteralExpression>());
@@ -147,10 +147,10 @@
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::VariableDeclStatement>());
- ASSERT_EQ(e->source.range.begin.line, 1u);
- ASSERT_EQ(e->source.range.begin.column, 5u);
- ASSERT_EQ(e->source.range.end.line, 1u);
- ASSERT_EQ(e->source.range.end.column, 6u);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 1u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 12u);
}
TEST_F(ParserImplTest, VariableStmt_Let_ComplexExpression) {
diff --git a/src/tint/resolver/attribute_validation_test.cc b/src/tint/resolver/attribute_validation_test.cc
index 86d6825..762eea9 100644
--- a/src/tint/resolver/attribute_validation_test.cc
+++ b/src/tint/resolver/attribute_validation_test.cc
@@ -1606,12 +1606,22 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
+TEST_F(GroupAndBindingTest, Binding_NonConstant) {
+ GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ Binding(Construct(ty.u32(), Call(Source{{12, 34}}, "dpdx", 1_a))), Group(1_i));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: @binding requires a const-expression, but expression is a runtime-expression)");
+}
+
TEST_F(GroupAndBindingTest, Binding_Negative) {
GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
Binding(Source{{12, 34}}, -2_i), Group(1_i));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: 'binding' value must be non-negative)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: @binding value must be non-negative)");
}
TEST_F(GroupAndBindingTest, Binding_F32) {
@@ -1619,7 +1629,7 @@
Binding(Source{{12, 34}}, 2.0_f), Group(1_u));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: 'binding' must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: @binding must be an i32 or u32 value)");
}
TEST_F(GroupAndBindingTest, Binding_AFloat) {
@@ -1627,7 +1637,17 @@
Binding(Source{{12, 34}}, 2.0_a), Group(1_u));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: 'binding' must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: @binding must be an i32 or u32 value)");
+}
+
+TEST_F(GroupAndBindingTest, Group_NonConstant) {
+ GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Binding(2_u),
+ Group(Construct(ty.u32(), Call(Source{{12, 34}}, "dpdx", 1_a))));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: @group requires a const-expression, but expression is a runtime-expression)");
}
TEST_F(GroupAndBindingTest, Group_Negative) {
@@ -1635,7 +1655,7 @@
Group(Source{{12, 34}}, -1_i));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: 'group' value must be non-negative)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: @group value must be non-negative)");
}
TEST_F(GroupAndBindingTest, Group_F32) {
@@ -1643,7 +1663,7 @@
Group(Source{{12, 34}}, 1.0_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: 'group' must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: @group must be an i32 or u32 value)");
}
TEST_F(GroupAndBindingTest, Group_AFloat) {
@@ -1651,7 +1671,7 @@
Group(Source{{12, 34}}, 1.0_a));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: 'group' must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: @group must be an i32 or u32 value)");
}
using IdTest = ResolverTest;
@@ -1671,24 +1691,125 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
+TEST_F(IdTest, NonConstant) {
+ Override("val", ty.f32(),
+ utils::Vector{Id(Construct(ty.u32(), Call(Source{{12, 34}}, "dpdx", 1_a)))});
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: @id requires a const-expression, but expression is a runtime-expression)");
+}
+
TEST_F(IdTest, Negative) {
Override("val", ty.f32(), utils::Vector{Id(Source{{12, 34}}, -1_i)});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: 'id' value must be non-negative)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: @id value must be non-negative)");
}
TEST_F(IdTest, F32) {
Override("val", ty.f32(), utils::Vector{Id(Source{{12, 34}}, 1_f)});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: 'id' must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: @id must be an i32 or u32 value)");
}
TEST_F(IdTest, AFloat) {
Override("val", ty.f32(), utils::Vector{Id(Source{{12, 34}}, 1.0_a)});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: 'id' must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: @id must be an i32 or u32 value)");
}
+enum class LocationAttributeType {
+ kEntryPointParameter,
+ kEntryPointReturnType,
+ kStructureMember,
+};
+
+struct LocationTest : ResolverTestWithParam<LocationAttributeType> {
+ void Build(const ast::Expression* location_value) {
+ switch (GetParam()) {
+ case LocationAttributeType::kEntryPointParameter:
+ Func("main",
+ utils::Vector{Param(Source{{12, 34}}, "a", ty.i32(),
+ utils::Vector{
+ Location(Source{{12, 34}}, location_value),
+ Flat(),
+ })},
+ ty.void_(), utils::Empty,
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
+ return;
+ case LocationAttributeType::kEntryPointReturnType:
+ Func("main", utils::Empty, ty.f32(),
+ utils::Vector{
+ Return(1_a),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ },
+ utils::Vector{
+ Location(Source{{12, 34}}, location_value),
+ });
+ return;
+ case LocationAttributeType::kStructureMember:
+ Structure("S", utils::Vector{
+ Member("m", ty.f32(),
+ utils::Vector{
+ Location(Source{{12, 34}}, location_value),
+ }),
+ });
+ return;
+ }
+ }
+};
+
+TEST_P(LocationTest, Const_I32) {
+ Build(Expr(0_i));
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_P(LocationTest, Const_U32) {
+ Build(Expr(0_u));
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_P(LocationTest, Const_AInt) {
+ Build(Expr(0_a));
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_P(LocationTest, NonConstant) {
+ Build(Construct(ty.u32(), Call(Source{{12, 34}}, "dpdx", 1_a)));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: @location value requires a const-expression, but expression is a runtime-expression)");
+}
+
+TEST_P(LocationTest, Negative) {
+ Build(Expr(-1_a));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), R"(12:34 error: @location value must be non-negative)");
+}
+
+TEST_P(LocationTest, F32) {
+ Build(Expr(1_f));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), R"(12:34 error: @location must be an i32 or u32 value)");
+}
+
+TEST_P(LocationTest, AFloat) {
+ Build(Expr(1.0_a));
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), R"(12:34 error: @location must be an i32 or u32 value)");
+}
+
+INSTANTIATE_TEST_SUITE_P(LocationTest,
+ LocationTest,
+ testing::Values(LocationAttributeType::kEntryPointParameter,
+ LocationAttributeType::kEntryPointReturnType,
+ LocationAttributeType::kStructureMember));
+
} // namespace
} // namespace InterpolateTests
diff --git a/src/tint/resolver/builtin_test.cc b/src/tint/resolver/builtin_test.cc
index 7c15767..c3911fb 100644
--- a/src/tint/resolver/builtin_test.cc
+++ b/src/tint/resolver/builtin_test.cc
@@ -61,12 +61,10 @@
}
TEST_F(ResolverBuiltinTest, ModuleScopeUsage) {
- GlobalConst("c", ty.f32(), Call(Source{{12, 34}}, "abs", 1._f));
+ GlobalConst("c", ty.f32(), Call(Source{{12, 34}}, "dpdy", 1._f));
EXPECT_FALSE(r()->Resolve());
- // TODO(crbug.com/tint/1581): Once 'abs' is implemented as @const, this will no longer be an
- // error.
EXPECT_EQ(
r()->error(),
R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression)");
diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc
index b61151d..afb9f5d 100644
--- a/src/tint/resolver/const_eval.cc
+++ b/src/tint/resolver/const_eval.cc
@@ -15,6 +15,7 @@
#include "src/tint/resolver/const_eval.h"
#include <algorithm>
+#include <iomanip>
#include <limits>
#include <optional>
#include <string>
@@ -187,14 +188,24 @@
template <typename NumberT>
std::string OverflowErrorMessage(NumberT lhs, const char* op, NumberT rhs) {
std::stringstream ss;
+ ss << std::setprecision(20);
ss << "'" << lhs.value << " " << op << " " << rhs.value << "' cannot be represented as '"
<< FriendlyName<NumberT>() << "'";
return ss.str();
}
+template <typename VALUE_TY>
+std::string OverflowErrorMessage(VALUE_TY value, std::string_view target_ty) {
+ std::stringstream ss;
+ ss << std::setprecision(20);
+ ss << "value " << value << " cannot be represented as "
+ << "'" << target_ty << "'";
+ return ss.str();
+}
+
/// @returns the number of consecutive leading bits in `@p e` set to `@p bit_value_to_count`.
template <typename T>
-auto CountLeadingBits(T e, T bit_value_to_count) -> std::make_unsigned_t<T> {
+std::make_unsigned_t<T> CountLeadingBits(T e, T bit_value_to_count) {
using UT = std::make_unsigned_t<T>;
constexpr UT kNumBits = sizeof(UT) * 8;
constexpr UT kLeftMost = UT{1} << (kNumBits - 1);
@@ -211,7 +222,7 @@
/// @returns the number of consecutive trailing bits set to `@p bit_value_to_count` in `@p e`
template <typename T>
-auto CountTrailingBits(T e, T bit_value_to_count) -> std::make_unsigned_t<T> {
+std::make_unsigned_t<T> CountTrailingBits(T e, T bit_value_to_count) {
using UT = std::make_unsigned_t<T>;
constexpr UT kNumBits = sizeof(UT) * 8;
constexpr UT kRightMost = UT{1};
@@ -292,10 +303,9 @@
// --- Below this point are the failure cases ---
} else if constexpr (IsAbstract<FROM>) {
// [abstract-numeric -> x] - materialization failure
- std::stringstream ss;
- ss << "value " << value << " cannot be represented as ";
- ss << "'" << builder.FriendlyName(target_ty) << "'";
- builder.Diagnostics().add_error(tint::diag::System::Resolver, ss.str(), source);
+ builder.Diagnostics().add_error(
+ tint::diag::System::Resolver,
+ OverflowErrorMessage(value, builder.FriendlyName(target_ty)), source);
return utils::Failure;
} else if constexpr (IsFloatingPoint<TO>) {
// [x -> floating-point] - number not exactly representable
@@ -1570,6 +1580,54 @@
return r;
}
+ConstEval::Result ConstEval::abs(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
+ auto transform = [&](const sem::Constant* c0) {
+ auto create = [&](auto e) {
+ using NumberT = decltype(e);
+ NumberT result;
+ if constexpr (IsUnsignedIntegral<NumberT>) {
+ result = e;
+ } else if constexpr (IsSignedIntegral<NumberT>) {
+ if (e == NumberT::Lowest()) {
+ result = e;
+ } else {
+ result = NumberT{std::abs(e)};
+ }
+ } else {
+ result = NumberT{std::abs(e)};
+ }
+ return CreateElement(builder, c0->Type(), result);
+ };
+ return Dispatch_fia_fiu32_f16(create, c0);
+ };
+ return TransformElements(builder, ty, transform, args[0]);
+}
+
+ConstEval::Result ConstEval::acos(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source) {
+ auto transform = [&](const sem::Constant* c0) {
+ auto create = [&](auto i) -> ImplResult {
+ using NumberT = decltype(i);
+ if (i < NumberT(-1.0) || i > NumberT(1.0)) {
+ AddError("acos must be called with a value in the range [-1 .. 1] (inclusive)", source);
+ return utils::Failure;
+ }
+ return CreateElement(builder, c0->Type(), NumberT(std::acos(i.value)));
+ };
+ return Dispatch_fa_f32_f16(create, c0);
+ };
+ return TransformElements(builder, ty, transform, args[0]);
+}
+
+ConstEval::Result ConstEval::all(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
+ return CreateElement(builder, ty, !args[0]->AnyZero());
+}
+
ConstEval::Result ConstEval::any(const sem::Type* ty,
utils::VectorRef<const sem::Constant*> args,
const Source&) {
@@ -1582,11 +1640,11 @@
auto transform = [&](const sem::Constant* c0) {
auto create = [&](auto i) -> ImplResult {
using NumberT = decltype(i);
- if (i.value < NumberT(-1.0) || i.value > NumberT(1.0)) {
- AddError("asin must be called with a value in the range [-1, 1]", source);
+ if (i < NumberT(-1.0) || i > NumberT(1.0)) {
+ AddError("asin must be called with a value in the range [-1 .. 1] (inclusive)", source);
return utils::Failure;
}
- return CreateElement(builder, c0->Type(), decltype(i)(std::asin(i.value)));
+ return CreateElement(builder, c0->Type(), NumberT(std::asin(i.value)));
};
return Dispatch_fa_f32_f16(create, c0);
};
@@ -1628,11 +1686,11 @@
auto transform = [&](const sem::Constant* c0) {
auto create = [&](auto i) -> ImplResult {
using NumberT = decltype(i);
- if (i.value <= NumberT(-1.0) || i.value >= NumberT(1.0)) {
- AddError("atanh must be called with a value in the range (-1, 1)", source);
+ if (i <= NumberT(-1.0) || i >= NumberT(1.0)) {
+ AddError("atanh must be called with a value in the range (-1 .. 1) (exclusive)", source);
return utils::Failure;
}
- return CreateElement(builder, c0->Type(), decltype(i)(std::atanh(i.value)));
+ return CreateElement(builder, c0->Type(), NumberT(std::atanh(i.value)));
};
return Dispatch_fa_f32_f16(create, c0);
};
@@ -1652,6 +1710,18 @@
return TransformElements(builder, ty, transform, args[0], args[1]);
}
+ConstEval::Result ConstEval::ceil(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
+ auto transform = [&](const sem::Constant* c0) {
+ auto create = [&](auto e) {
+ return CreateElement(builder, c0->Type(), decltype(e)(std::ceil(e)));
+ };
+ return Dispatch_fa_f32_f16(create, c0);
+ };
+ return TransformElements(builder, ty, transform, args[0]);
+}
+
ConstEval::Result ConstEval::clamp(const sem::Type* ty,
utils::VectorRef<const sem::Constant*> args,
const Source&) {
@@ -1720,6 +1790,61 @@
return TransformElements(builder, ty, transform, args[0]);
}
+ConstEval::Result ConstEval::extractBits(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source) {
+ auto transform = [&](const sem::Constant* c0) {
+ auto create = [&](auto in_e) -> ImplResult {
+ using NumberT = decltype(in_e);
+ using T = UnwrapNumber<NumberT>;
+ using UT = std::make_unsigned_t<T>;
+ using NumberUT = Number<UT>;
+
+ // Read args that are always scalar
+ NumberUT in_offset = args[1]->As<NumberUT>();
+ NumberUT in_count = args[2]->As<NumberUT>();
+
+ constexpr UT w = sizeof(UT) * 8;
+ if ((in_offset + in_count) > w) {
+ AddError("'offset + 'count' must be less than or equal to the bit width of 'e'",
+ source);
+ return utils::Failure;
+ }
+
+ // Cast all to unsigned
+ UT e = static_cast<UT>(in_e);
+ UT o = static_cast<UT>(in_offset);
+ UT c = static_cast<UT>(in_count);
+
+ NumberT result;
+ if (c == UT{0}) {
+ // The result is 0 if c is 0
+ result = NumberT{0};
+ } else if (c == w) {
+ // The result is e if c is w
+ result = NumberT{e};
+ } else {
+ // Otherwise, bits 0..c - 1 of the result are copied from bits o..o + c - 1 of e.
+ UT src_mask = ((UT{1} << c) - UT{1}) << o;
+ UT r = (e & src_mask) >> o;
+ if constexpr (IsSignedIntegral<NumberT>) {
+ // Other bits of the result are the same as bit c - 1 of the result.
+ // Only need to set other bits if bit at c - 1 of result is 1
+ if ((r & (UT{1} << (c - UT{1}))) != UT{0}) {
+ UT dst_mask = src_mask >> o;
+ r |= (~UT{0} & ~dst_mask);
+ }
+ }
+
+ result = NumberT{r};
+ }
+ return CreateElement(builder, c0->Type(), result);
+ };
+ return Dispatch_iu32(create, c0);
+ };
+ return TransformElements(builder, ty, transform, args[0]);
+}
+
ConstEval::Result ConstEval::firstLeadingBit(const sem::Type* ty,
utils::VectorRef<const sem::Constant*> args,
const Source&) {
@@ -1790,6 +1915,97 @@
return TransformElements(builder, ty, transform, args[0]);
}
+ConstEval::Result ConstEval::floor(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
+ auto transform = [&](const sem::Constant* c0) {
+ auto create = [&](auto e) {
+ return CreateElement(builder, c0->Type(), decltype(e)(std::floor(e)));
+ };
+ return Dispatch_fa_f32_f16(create, c0);
+ };
+ return TransformElements(builder, ty, transform, args[0]);
+}
+
+ConstEval::Result ConstEval::insertBits(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source) {
+ auto transform = [&](const sem::Constant* c0, const sem::Constant* c1) {
+ auto create = [&](auto in_e, auto in_newbits) -> ImplResult {
+ using NumberT = decltype(in_e);
+ using T = UnwrapNumber<NumberT>;
+ using UT = std::make_unsigned_t<T>;
+ using NumberUT = Number<UT>;
+
+ // Read args that are always scalar
+ NumberUT in_offset = args[2]->As<NumberUT>();
+ NumberUT in_count = args[3]->As<NumberUT>();
+
+ constexpr UT w = sizeof(UT) * 8;
+ if ((in_offset + in_count) > w) {
+ AddError("'offset + 'count' must be less than or equal to the bit width of 'e'",
+ source);
+ return utils::Failure;
+ }
+
+ // Cast all to unsigned
+ UT e = static_cast<UT>(in_e);
+ UT newbits = static_cast<UT>(in_newbits);
+ UT o = static_cast<UT>(in_offset);
+ UT c = static_cast<UT>(in_count);
+
+ NumberT result;
+ if (c == UT{0}) {
+ // The result is e if c is 0
+ result = NumberT{e};
+ } else if (c == w) {
+ // The result is newbits if c is w
+ result = NumberT{newbits};
+ } else {
+ // Otherwise, bits o..o + c - 1 of the result are copied from bits 0..c - 1 of
+ // newbits. Other bits of the result are copied from e.
+ UT from = newbits << o;
+ UT mask = ((UT{1} << c) - UT{1}) << UT{o};
+ auto r = e; // Start with 'e' as the result
+ r &= ~mask; // Zero the bits in 'e' we're overwriting
+ r |= (from & mask); // Overwrite from 'newbits' (shifted into position)
+ result = NumberT{r};
+ }
+
+ return CreateElement(builder, c0->Type(), result);
+ };
+ return Dispatch_iu32(create, c0, c1);
+ };
+ return TransformElements(builder, ty, transform, args[0], args[1]);
+}
+
+ConstEval::Result ConstEval::reverseBits(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
+ auto transform = [&](const sem::Constant* c0) {
+ auto create = [&](auto in_e) -> ImplResult {
+ using NumberT = decltype(in_e);
+ using T = UnwrapNumber<NumberT>;
+ using UT = std::make_unsigned_t<T>;
+ constexpr UT kNumBits = sizeof(UT) * 8;
+
+ UT e = static_cast<UT>(in_e);
+ UT r = UT{0};
+ for (size_t s = 0; s < kNumBits; ++s) {
+ // Write source 's' bit to destination 'd' bit if 1
+ if (e & (UT{1} << s)) {
+ size_t d = kNumBits - s - 1;
+ r |= (UT{1} << d);
+ }
+ }
+
+ return CreateElement(builder, c0->Type(), NumberT{r});
+ };
+ return Dispatch_iu32(create, c0);
+ };
+ return TransformElements(builder, ty, transform, args[0]);
+}
+
ConstEval::Result ConstEval::saturate(const sem::Type* ty,
utils::VectorRef<const sem::Constant*> args,
const Source&) {
@@ -1869,6 +2085,27 @@
return TransformElements(builder, ty, transform, args[0], args[1]);
}
+ConstEval::Result ConstEval::quantizeToF16(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source&) {
+ auto transform = [&](const sem::Constant* c) {
+ auto conv = CheckedConvert<f32>(f16(c->As<f32>()));
+ if (!conv) {
+ // https://www.w3.org/TR/WGSL/#quantizeToF16-builtin
+ // If e is outside the finite range of binary16, then the result is any value of type
+ // f32
+ switch (conv.Failure()) {
+ case ConversionFailure::kExceedsNegativeLimit:
+ return CreateElement(builder, c->Type(), f16(f16::kLowestValue));
+ case ConversionFailure::kExceedsPositiveLimit:
+ return CreateElement(builder, c->Type(), f16(f16::kHighestValue));
+ }
+ }
+ return CreateElement(builder, c->Type(), conv.Get());
+ };
+ return TransformElements(builder, ty, transform, args[0]);
+}
+
ConstEval::Result ConstEval::Convert(const sem::Type* target_ty,
const sem::Constant* value,
const Source& source) {
diff --git a/src/tint/resolver/const_eval.h b/src/tint/resolver/const_eval.h
index 91189fa..f309150 100644
--- a/src/tint/resolver/const_eval.h
+++ b/src/tint/resolver/const_eval.h
@@ -377,6 +377,33 @@
// Builtins
////////////////////////////////////////////////////////////////////////////
+ /// abs builtin
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location of the conversion
+ /// @return the result value, or null if the value cannot be calculated
+ Result abs(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
+ /// all builtin
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location of the conversion
+ /// @return the result value, or null if the value cannot be calculated
+ Result all(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
+ /// acos builtin
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location of the conversion
+ /// @return the result value, or null if the value cannot be calculated
+ Result acos(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
/// any builtin
/// @param ty the expression type
/// @param args the input arguments
@@ -431,6 +458,15 @@
utils::VectorRef<const sem::Constant*> args,
const Source& source);
+ /// ceil builtin
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location of the conversion
+ /// @return the result value, or null if the value cannot be calculated
+ Result ceil(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
/// clamp builtin
/// @param ty the expression type
/// @param args the input arguments
@@ -467,6 +503,15 @@
utils::VectorRef<const sem::Constant*> args,
const Source& source);
+ /// extractBits builtin
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location of the conversion
+ /// @return the result value, or null if the value cannot be calculated
+ Result extractBits(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
/// firstLeadingBit builtin
/// @param ty the expression type
/// @param args the input arguments
@@ -485,6 +530,33 @@
utils::VectorRef<const sem::Constant*> args,
const Source& source);
+ /// floor builtin
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location of the conversion
+ /// @return the result value, or null if the value cannot be calculated
+ Result floor(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
+ /// insertBits builtin
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location of the conversion
+ /// @return the result value, or null if the value cannot be calculated
+ Result insertBits(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
+ /// reverseBits builtin
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location of the conversion
+ /// @return the result value, or null if the value cannot be calculated
+ Result reverseBits(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
/// saturate builtin
/// @param ty the expression type
/// @param args the input arguments
@@ -530,6 +602,15 @@
utils::VectorRef<const sem::Constant*> args,
const Source& source);
+ /// quantizeToF16 builtin
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location of the conversion
+ /// @return the result value, or null if the value cannot be calculated
+ Result quantizeToF16(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
private:
/// Adds the given error message to the diagnostics
void AddError(const std::string& msg, const Source& source) const;
diff --git a/src/tint/resolver/const_eval_binary_op_test.cc b/src/tint/resolver/const_eval_binary_op_test.cc
index 05a1453..8708aa8 100644
--- a/src/tint/resolver/const_eval_binary_op_test.cc
+++ b/src/tint/resolver/const_eval_binary_op_test.cc
@@ -853,7 +853,7 @@
GlobalConst("c", Add(Source{{1, 1}}, Expr(AFloat::Highest()), AFloat::Highest()));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "1:1 error: '1.79769e+308 + 1.79769e+308' cannot be represented as 'abstract-float'");
+ "1:1 error: '1.7976931348623157081e+308 + 1.7976931348623157081e+308' cannot be represented as 'abstract-float'");
}
TEST_F(ResolverConstEvalTest, BinaryAbstractAddUnderflow_AFloat) {
@@ -861,7 +861,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- "1:1 error: '-1.79769e+308 + -1.79769e+308' cannot be represented as 'abstract-float'");
+ "1:1 error: '-1.7976931348623157081e+308 + -1.7976931348623157081e+308' cannot be represented as 'abstract-float'");
}
// Mixed AInt and AFloat args to test implicit conversion to AFloat
diff --git a/src/tint/resolver/const_eval_builtin_test.cc b/src/tint/resolver/const_eval_builtin_test.cc
index 3c275cb..3dc395b 100644
--- a/src/tint/resolver/const_eval_builtin_test.cc
+++ b/src/tint/resolver/const_eval_builtin_test.cc
@@ -14,6 +14,8 @@
#include "src/tint/resolver/const_eval_test.h"
+#include "src/tint/utils/result.h"
+
using namespace tint::number_suffixes; // NOLINT
namespace tint::resolver {
@@ -23,25 +25,39 @@
using resolver::operator<<;
struct Case {
- Case(utils::VectorRef<Types> in_args, Types in_expected)
- : args(std::move(in_args)), expected(std::move(in_expected)) {}
+ Case(utils::VectorRef<Types> in_args, Types expected_value)
+ : args(std::move(in_args)), expected(Success{std::move(expected_value), false, false}) {}
+
+ Case(utils::VectorRef<Types> in_args, const char* expected_err)
+ : args(std::move(in_args)), expected(Failure{expected_err}) {}
/// Expected value may be positive or negative
Case& PosOrNeg() {
- expected_pos_or_neg = true;
+ Success s = expected.Get();
+ s.pos_or_neg = true;
+ expected = s;
return *this;
}
/// Expected value should be compared using FLOAT_EQ instead of EQ
Case& FloatComp() {
- float_compare = true;
+ Success s = expected.Get();
+ s.float_compare = true;
+ expected = s;
return *this;
}
+ struct Success {
+ Types value;
+ bool pos_or_neg = false;
+ bool float_compare = false;
+ };
+ struct Failure {
+ const char* error = nullptr;
+ };
+
utils::Vector<Types, 8> args;
- Types expected;
- bool expected_pos_or_neg = false;
- bool float_compare = false;
+ utils::Result<Success, Failure> expected;
};
static std::ostream& operator<<(std::ostream& o, const Case& c) {
@@ -49,17 +65,24 @@
for (auto& a : c.args) {
o << a << ", ";
}
- o << "expected: " << c.expected << ", expected_pos_or_neg: " << c.expected_pos_or_neg;
+ o << "expected: ";
+ if (c.expected) {
+ auto s = c.expected.Get();
+ o << s.value << ", pos_or_neg: " << s.pos_or_neg;
+ } else {
+ o << "[ERROR: " << c.expected.Failure().error << "]";
+ }
return o;
}
+using ScalarTypes = std::variant<AInt, AFloat, u32, i32, f32, f16>;
+
/// Creates a Case with Values for args and result
static Case C(std::initializer_list<Types> args, Types result) {
return Case{utils::Vector<Types, 8>{args}, std::move(result)};
}
/// Convenience overload that creates a Case with just scalars
-using ScalarTypes = std::variant<AInt, AFloat, u32, i32, f32, f16>;
static Case C(std::initializer_list<ScalarTypes> sargs, ScalarTypes sresult) {
utils::Vector<Types, 8> args;
for (auto& sa : sargs) {
@@ -70,6 +93,20 @@
return Case{std::move(args), std::move(result)};
}
+/// Creates a Case with Values for args and expected error
+static Case E(std::initializer_list<Types> args, const char* err) {
+ return Case{utils::Vector<Types, 8>{args}, err};
+}
+
+/// Convenience overload that creates an expected-error Case with just scalars
+static Case E(std::initializer_list<ScalarTypes> sargs, const char* err) {
+ utils::Vector<Types, 8> args;
+ for (auto& sa : sargs) {
+ std::visit([&](auto&& v) { return args.Push(Val(v)); }, sa);
+ }
+ return Case{std::move(args), err};
+}
+
using ResolverConstEvalBuiltinTest = ResolverTestWithParam<std::tuple<sem::BuiltinType, Case>>;
TEST_P(ResolverConstEvalBuiltinTest, Test) {
@@ -83,58 +120,65 @@
std::visit([&](auto&& v) { args.Push(v.Expr(*this)); }, a);
}
- auto* expected = ToValueBase(c.expected);
- auto* expr = Call(sem::str(builtin), std::move(args));
+ auto* expr = Call(Source{{12, 34}}, sem::str(builtin), std::move(args));
GlobalConst("C", expr);
- auto* expected_expr = expected->Expr(*this);
- GlobalConst("E", expected_expr);
- ASSERT_TRUE(r()->Resolve()) << r()->error();
+ if (c.expected) {
+ auto expected = c.expected.Get();
- auto* sem = Sem().Get(expr);
- ASSERT_NE(sem, nullptr);
- const sem::Constant* value = sem->ConstantValue();
- ASSERT_NE(value, nullptr);
- EXPECT_TYPE(value->Type(), sem->Type());
+ auto* expected_expr = ToValueBase(expected.value)->Expr(*this);
+ GlobalConst("E", expected_expr);
- auto* expected_sem = Sem().Get(expected_expr);
- const sem::Constant* expected_value = expected_sem->ConstantValue();
- ASSERT_NE(expected_value, nullptr);
- EXPECT_TYPE(expected_value->Type(), expected_sem->Type());
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
- // @TODO(amaiorano): Rewrite using ScalarArgsFrom()
- ForEachElemPair(value, expected_value, [&](const sem::Constant* a, const sem::Constant* b) {
- std::visit(
- [&](auto&& ct_expected) {
- using T = typename std::decay_t<decltype(ct_expected)>::ElementType;
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ const sem::Constant* value = sem->ConstantValue();
+ ASSERT_NE(value, nullptr);
+ EXPECT_TYPE(value->Type(), sem->Type());
- auto v = a->As<T>();
- auto e = b->As<T>();
- if constexpr (std::is_same_v<bool, T>) {
- EXPECT_EQ(v, e);
- } else if constexpr (IsFloatingPoint<T>) {
- if (std::isnan(e)) {
- EXPECT_TRUE(std::isnan(v));
- } else {
- auto vf = (c.expected_pos_or_neg ? Abs(v) : v);
- if (c.float_compare) {
- EXPECT_FLOAT_EQ(vf, e);
+ auto* expected_sem = Sem().Get(expected_expr);
+ const sem::Constant* expected_value = expected_sem->ConstantValue();
+ ASSERT_NE(expected_value, nullptr);
+ EXPECT_TYPE(expected_value->Type(), expected_sem->Type());
+
+ // @TODO(amaiorano): Rewrite using ScalarArgsFrom()
+ ForEachElemPair(value, expected_value, [&](const sem::Constant* a, const sem::Constant* b) {
+ std::visit(
+ [&](auto&& ct_expected) {
+ using T = typename std::decay_t<decltype(ct_expected)>::ElementType;
+
+ auto v = a->As<T>();
+ auto e = b->As<T>();
+ if constexpr (std::is_same_v<bool, T>) {
+ EXPECT_EQ(v, e);
+ } else if constexpr (IsFloatingPoint<T>) {
+ if (std::isnan(e)) {
+ EXPECT_TRUE(std::isnan(v));
} else {
- EXPECT_EQ(vf, e);
+ auto vf = (expected.pos_or_neg ? Abs(v) : v);
+ if (expected.float_compare) {
+ EXPECT_FLOAT_EQ(vf, e);
+ } else {
+ EXPECT_EQ(vf, e);
+ }
}
+ } else {
+ EXPECT_EQ((expected.pos_or_neg ? Abs(v) : v), e);
+ // Check that the constant's integer doesn't contain unexpected
+ // data in the MSBs that are outside of the bit-width of T.
+ EXPECT_EQ(a->As<AInt>(), b->As<AInt>());
}
- } else {
- EXPECT_EQ((c.expected_pos_or_neg ? Abs(v) : v), e);
- // Check that the constant's integer doesn't contain unexpected
- // data in the MSBs that are outside of the bit-width of T.
- EXPECT_EQ(a->As<AInt>(), b->As<AInt>());
- }
- },
- c.expected);
+ },
+ expected.value);
- return HasFailure() ? Action::kStop : Action::kContinue;
- });
+ return HasFailure() ? Action::kStop : Action::kContinue;
+ });
+ } else {
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), c.expected.Failure().error);
+ }
}
INSTANTIATE_TEST_SUITE_P( //
@@ -146,6 +190,82 @@
C({1.0_a, 0_a}, kPiOver2<AFloat>),
})));
+template <typename T, bool finite_only>
+std::vector<Case> AbsCases() {
+ std::vector<Case> cases = {
+ C({T(0)}, T(0)),
+ C({T(2.0)}, T(2.0)),
+ C({T::Highest()}, T::Highest()),
+
+ // Vector tests
+ C({Vec(T(2.0), T::Highest())}, Vec(T(2.0), T::Highest())),
+ };
+
+ ConcatIntoIf<IsSignedIntegral<T>>(
+ cases,
+ std::vector<Case>{
+ C({Negate(T(0))}, T(0)),
+ C({Negate(T(2.0))}, T(2.0)),
+ // If e is signed and is the largest negative, the result is e
+ C({T::Lowest()}, T::Lowest()),
+
+ // 1 more then min i32
+ C({Negate(T(2147483647))}, T(2147483647)),
+
+ C({Vec(T(0), Negate(T(0)))}, Vec(T(0), T(0))),
+ C({Vec(Negate(T(2.0)), T(2.0), T::Highest())}, Vec(T(2.0), T(2.0), T::Highest())),
+ });
+
+ ConcatIntoIf<!finite_only>(cases, std::vector<Case>{
+ C({Negate(T::Inf())}, T::Inf()),
+ C({T::Inf()}, T::Inf()),
+ C({T::NaN()}, T::NaN()),
+ C({Vec(Negate(T::Inf()), T::Inf(), T::NaN())},
+ Vec(T::Inf(), T::Inf(), T::NaN())),
+ });
+
+ return cases;
+}
+INSTANTIATE_TEST_SUITE_P( //
+ Abs,
+ ResolverConstEvalBuiltinTest,
+ testing::Combine(testing::Values(sem::BuiltinType::kAbs),
+ testing::ValuesIn(Concat(AbsCases<AInt, false>(), //
+ AbsCases<i32, false>(),
+ AbsCases<u32, false>(),
+ AbsCases<AFloat, true>(),
+ AbsCases<f32, false>(),
+ AbsCases<f16, false>()))));
+
+static std::vector<Case> AllCases() {
+ return {
+ C({Val(true)}, Val(true)),
+ C({Val(false)}, Val(false)),
+
+ C({Vec(true, true)}, Val(true)),
+ C({Vec(true, false)}, Val(false)),
+ C({Vec(false, true)}, Val(false)),
+ C({Vec(false, false)}, Val(false)),
+
+ C({Vec(true, true, true)}, Val(true)),
+ C({Vec(false, true, true)}, Val(false)),
+ C({Vec(true, false, true)}, Val(false)),
+ C({Vec(true, true, false)}, Val(false)),
+ C({Vec(false, false, false)}, Val(false)),
+
+ C({Vec(true, true, true, true)}, Val(true)),
+ C({Vec(false, true, true, true)}, Val(false)),
+ C({Vec(true, false, true, true)}, Val(false)),
+ C({Vec(true, true, false, true)}, Val(false)),
+ C({Vec(true, true, true, false)}, Val(false)),
+ C({Vec(false, false, false, false)}, Val(false)),
+ };
+}
+INSTANTIATE_TEST_SUITE_P( //
+ All,
+ ResolverConstEvalBuiltinTest,
+ testing::Combine(testing::Values(sem::BuiltinType::kAll), testing::ValuesIn(AllCases())));
+
static std::vector<Case> AnyCases() {
return {
C({Val(true)}, Val(true)),
@@ -298,6 +418,19 @@
C({Vec(T(0.0), T(0.9), -T(0.9))}, Vec(T(0.0), T(1.4722193), -T(1.4722193))).FloatComp(),
};
+ ConcatIntoIf<finite_only>( //
+ cases,
+ std::vector<Case>{
+ E({1.1_a},
+ "12:34 error: atanh must be called with a value in the range (-1 .. 1) (exclusive)"),
+ E({-1.1_a},
+ "12:34 error: atanh must be called with a value in the range (-1 .. 1) (exclusive)"),
+ E({T::Inf()},
+ "12:34 error: atanh must be called with a value in the range (-1 .. 1) (exclusive)"),
+ E({-T::Inf()},
+ "12:34 error: atanh must be called with a value in the range (-1 .. 1) (exclusive)"),
+ });
+
ConcatIntoIf<!finite_only>( //
cases, std::vector<Case>{
// If i is NaN, NaN is returned
@@ -317,37 +450,50 @@
AtanhCases<f32, false>(),
AtanhCases<f16, false>()))));
-TEST_F(ResolverConstEvalBuiltinTest, Atanh_OutsideRange_Positive) {
- auto* expr = Call(Source{{12, 24}}, "atanh", Expr(1.0_a));
+template <typename T, bool finite_only>
+std::vector<Case> AcosCases() {
+ std::vector<Case> cases = {
+ // If i is +/-0, +/-0 is returned
+ C({T(0.87758256189)}, T(0.5)).FloatComp(),
- GlobalConst("C", expr);
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:24 error: atanh must be called with a value in the range (-1, 1)");
+ C({T(1.0)}, T(0.0)),
+ C({-T(1.0)}, kPi<T>).FloatComp(),
+
+ // Vector tests
+ C({Vec(T(1.0), -T(1.0))}, Vec(T(0), kPi<T>)).FloatComp(),
+ };
+
+ ConcatIntoIf<finite_only>( //
+ cases,
+ std::vector<Case>{
+ E({1.1_a},
+ "12:34 error: acos must be called with a value in the range [-1 .. 1] (inclusive)"),
+ E({-1.1_a},
+ "12:34 error: acos must be called with a value in the range [-1 .. 1] (inclusive)"),
+ E({T::Inf()},
+ "12:34 error: acos must be called with a value in the range [-1 .. 1] (inclusive)"),
+ E({-T::Inf()},
+ "12:34 error: acos must be called with a value in the range [-1 .. 1] (inclusive)"),
+ });
+
+ ConcatIntoIf<!finite_only>( //
+ cases, std::vector<Case>{
+ // If i is NaN, NaN is returned
+ C({T::NaN()}, T::NaN()),
+
+ // Vector tests
+ C({Vec(T::NaN(), T::NaN())}, Vec(T::NaN(), T::NaN())),
+ });
+
+ return cases;
}
-
-TEST_F(ResolverConstEvalBuiltinTest, Atanh_OutsideRange_Negative) {
- auto* expr = Call(Source{{12, 24}}, "atanh", Negation(1.0_a));
-
- GlobalConst("C", expr);
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:24 error: atanh must be called with a value in the range (-1, 1)");
-}
-
-TEST_F(ResolverConstEvalBuiltinTest, Atanh_OutsideRange_Positive_INF) {
- auto* expr = Call(Source{{12, 24}}, "atanh", Expr(f32::Inf()));
-
- GlobalConst("C", expr);
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:24 error: atanh must be called with a value in the range (-1, 1)");
-}
-
-TEST_F(ResolverConstEvalBuiltinTest, Atanh_OutsideRange_Negative_INF) {
- auto* expr = Call(Source{{12, 24}}, "atanh", Negation(f32::Inf()));
-
- GlobalConst("C", expr);
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:24 error: atanh must be called with a value in the range (-1, 1)");
-}
+INSTANTIATE_TEST_SUITE_P( //
+ Acos,
+ ResolverConstEvalBuiltinTest,
+ testing::Combine(testing::Values(sem::BuiltinType::kAcos),
+ testing::ValuesIn(Concat(AcosCases<AFloat, true>(), //
+ AcosCases<f32, false>(),
+ AcosCases<f16, false>()))));
template <typename T, bool finite_only>
std::vector<Case> AsinCases() {
@@ -363,6 +509,19 @@
C({Vec(T(0.0), T(1.0), -T(1.0))}, Vec(T(0.0), kPiOver2<T>, -kPiOver2<T>)).FloatComp(),
};
+ ConcatIntoIf<finite_only>( //
+ cases,
+ std::vector<Case>{
+ E({1.1_a},
+ "12:34 error: asin must be called with a value in the range [-1 .. 1] (inclusive)"),
+ E({-1.1_a},
+ "12:34 error: asin must be called with a value in the range [-1 .. 1] (inclusive)"),
+ E({T::Inf()},
+ "12:34 error: asin must be called with a value in the range [-1 .. 1] (inclusive)"),
+ E({-T::Inf()},
+ "12:34 error: asin must be called with a value in the range [-1 .. 1] (inclusive)"),
+ });
+
ConcatIntoIf<!finite_only>( //
cases, std::vector<Case>{
// If i is NaN, NaN is returned
@@ -382,38 +541,6 @@
AsinCases<f32, false>(),
AsinCases<f16, false>()))));
-TEST_F(ResolverConstEvalBuiltinTest, Asin_OutsideRange_Positive) {
- auto* expr = Call(Source{{12, 24}}, "asin", Expr(1.1_a));
-
- GlobalConst("C", expr);
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:24 error: asin must be called with a value in the range [-1, 1]");
-}
-
-TEST_F(ResolverConstEvalBuiltinTest, Asin_OutsideRange_Negative) {
- auto* expr = Call(Source{{12, 24}}, "asin", Negation(1.1_a));
-
- GlobalConst("C", expr);
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:24 error: asin must be called with a value in the range [-1, 1]");
-}
-
-TEST_F(ResolverConstEvalBuiltinTest, Asin_OutsideRange_Positive_INF) {
- auto* expr = Call(Source{{12, 24}}, "asin", Expr(f32::Inf()));
-
- GlobalConst("C", expr);
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:24 error: asin must be called with a value in the range [-1, 1]");
-}
-
-TEST_F(ResolverConstEvalBuiltinTest, Asin_OutsideRange_Negative_INF) {
- auto* expr = Call(Source{{12, 24}}, "asin", Negation(f32::Inf()));
-
- GlobalConst("C", expr);
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:24 error: asin must be called with a value in the range [-1, 1]");
-}
-
template <typename T, bool finite_only>
std::vector<Case> AsinhCases() {
std::vector<Case> cases = {
@@ -454,6 +581,37 @@
AsinhCases<f32, false>(),
AsinhCases<f16, false>()))));
+template <typename T, bool finite_only>
+std::vector<Case> CeilCases() {
+ std::vector<Case> cases = {
+ C({T(0)}, T(0)),
+ C({-T(0)}, -T(0)),
+ C({-T(1.5)}, -T(1.0)),
+ C({T(1.5)}, T(2.0)),
+ C({T::Lowest()}, T::Lowest()),
+ C({T::Highest()}, T::Highest()),
+
+ C({Vec(T(0), T(1.5), -T(1.5))}, Vec(T(0), T(2.0), -T(1.0))),
+ };
+
+ ConcatIntoIf<!finite_only>(
+ cases, std::vector<Case>{
+ C({-T::Inf()}, -T::Inf()),
+ C({T::Inf()}, T::Inf()),
+ C({T::NaN()}, T::NaN()),
+ C({Vec(-T::Inf(), T::Inf(), T::NaN())}, Vec(-T::Inf(), T::Inf(), T::NaN())),
+ });
+
+ return cases;
+}
+INSTANTIATE_TEST_SUITE_P( //
+ Ceil,
+ ResolverConstEvalBuiltinTest,
+ testing::Combine(testing::Values(sem::BuiltinType::kCeil),
+ testing::ValuesIn(Concat(CeilCases<AFloat, true>(),
+ CeilCases<f32, false>(),
+ CeilCases<f16, false>()))));
+
template <typename T>
std::vector<Case> ClampCases() {
return {
@@ -713,6 +871,274 @@
testing::ValuesIn(Concat(FirstTrailingBitCases<i32>(), //
FirstTrailingBitCases<u32>()))));
+template <typename T, bool finite_only>
+std::vector<Case> FloorCases() {
+ std::vector<Case> cases = {
+ C({T(0)}, T(0)),
+ C({-T(0)}, -T(0)),
+ C({-T(1.5)}, -T(2.0)),
+ C({T(1.5)}, T(1.0)),
+ C({T::Lowest()}, T::Lowest()),
+ C({T::Highest()}, T::Highest()),
+
+ C({Vec(T(0), T(1.5), -T(1.5))}, Vec(T(0), T(1.0), -T(2.0))),
+ };
+
+ ConcatIntoIf<!finite_only>(
+ cases, std::vector<Case>{
+ C({-T::Inf()}, -T::Inf()),
+ C({T::Inf()}, T::Inf()),
+ C({T::NaN()}, T::NaN()),
+ C({Vec(-T::Inf(), T::Inf(), T::NaN())}, Vec(-T::Inf(), T::Inf(), T::NaN())),
+ });
+
+ return cases;
+}
+INSTANTIATE_TEST_SUITE_P( //
+ Floor,
+ ResolverConstEvalBuiltinTest,
+ testing::Combine(testing::Values(sem::BuiltinType::kFloor),
+ testing::ValuesIn(Concat(FloorCases<AFloat, true>(),
+ FloorCases<f32, false>(),
+ FloorCases<f16, false>()))));
+
+template <typename T>
+std::vector<Case> InsertBitsCases() {
+ using UT = Number<std::make_unsigned_t<UnwrapNumber<T>>>;
+
+ auto e = /* */ T(0b0101'1100'0011'1010'0101'1100'0011'1010);
+ auto newbits = T{0b1010'0011'1100'0101'1010'0011'1100'0101};
+
+ auto r = std::vector<Case>{
+ // args: e, newbits, offset, count
+
+ // If count is 0, result is e
+ C({e, newbits, UT(0), UT(0)}, e), //
+ C({e, newbits, UT(1), UT(0)}, e), //
+ C({e, newbits, UT(2), UT(0)}, e), //
+ C({e, newbits, UT(3), UT(0)}, e), //
+ // ...
+ C({e, newbits, UT(29), UT(0)}, e), //
+ C({e, newbits, UT(30), UT(0)}, e), //
+ C({e, newbits, UT(31), UT(0)}, e),
+
+ // Copy 1 to 32 bits of newbits to e at offset 0
+ C({e, newbits, UT(0), UT(1)}, T(0b0101'1100'0011'1010'0101'1100'0011'1011)),
+ C({e, newbits, UT(0), UT(2)}, T(0b0101'1100'0011'1010'0101'1100'0011'1001)),
+ C({e, newbits, UT(0), UT(3)}, T(0b0101'1100'0011'1010'0101'1100'0011'1101)),
+ C({e, newbits, UT(0), UT(4)}, T(0b0101'1100'0011'1010'0101'1100'0011'0101)),
+ C({e, newbits, UT(0), UT(5)}, T(0b0101'1100'0011'1010'0101'1100'0010'0101)),
+ C({e, newbits, UT(0), UT(6)}, T(0b0101'1100'0011'1010'0101'1100'0000'0101)),
+ // ...
+ C({e, newbits, UT(0), UT(29)}, T(0b0100'0011'1100'0101'1010'0011'1100'0101)),
+ C({e, newbits, UT(0), UT(30)}, T(0b0110'0011'1100'0101'1010'0011'1100'0101)),
+ C({e, newbits, UT(0), UT(31)}, T(0b0010'0011'1100'0101'1010'0011'1100'0101)),
+ C({e, newbits, UT(0), UT(32)}, T(0b1010'0011'1100'0101'1010'0011'1100'0101)),
+
+ // Copy at varying offsets and counts
+ C({e, newbits, UT(3), UT(8)}, T(0b0101'1100'0011'1010'0101'1110'0010'1010)),
+ C({e, newbits, UT(8), UT(8)}, T(0b0101'1100'0011'1010'1100'0101'0011'1010)),
+ C({e, newbits, UT(15), UT(1)}, T(0b0101'1100'0011'1010'1101'1100'0011'1010)),
+ C({e, newbits, UT(16), UT(16)}, T(0b1010'0011'1100'0101'0101'1100'0011'1010)),
+
+ // Vector tests
+ C({Vec(T(0b1111'0000'1111'0000'1111'0000'1111'0000), //
+ T(0b0000'1111'0000'1111'0000'1111'0000'1111), //
+ T(0b1010'0101'1010'0101'1010'0101'1010'0101)),
+ Vec(T(0b1111'1111'1111'1111'1111'1111'1111'1111), //
+ T(0b1111'1111'1111'1111'1111'1111'1111'1111), //
+ T(0b1111'1111'1111'1111'1111'1111'1111'1111)),
+ Val(UT(3)), Val(UT(8))},
+ Vec(T(0b1111'0000'1111'0000'1111'0111'1111'1000), //
+ T(0b0000'1111'0000'1111'0000'1111'1111'1111), //
+ T(0b1010'0101'1010'0101'1010'0111'1111'1101))),
+ };
+
+ return r;
+}
+INSTANTIATE_TEST_SUITE_P( //
+ InsertBits,
+ ResolverConstEvalBuiltinTest,
+ testing::Combine(testing::Values(sem::BuiltinType::kInsertBits),
+ testing::ValuesIn(Concat(InsertBitsCases<i32>(), //
+ InsertBitsCases<u32>()))));
+
+using ResolverConstEvalBuiltinTest_InsertBits_InvalidOffsetAndCount =
+ ResolverTestWithParam<std::tuple<size_t, size_t>>;
+TEST_P(ResolverConstEvalBuiltinTest_InsertBits_InvalidOffsetAndCount, Test) {
+ auto& p = GetParam();
+ auto* expr = Call(Source{{12, 34}}, sem::str(sem::BuiltinType::kInsertBits), Expr(1_u),
+ Expr(1_u), Expr(u32(std::get<0>(p))), Expr(u32(std::get<1>(p))));
+ GlobalConst("C", expr);
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "12:34 error: 'offset + 'count' must be less than or equal to the bit width of 'e'");
+}
+INSTANTIATE_TEST_SUITE_P(InsertBits,
+ ResolverConstEvalBuiltinTest_InsertBits_InvalidOffsetAndCount,
+ testing::Values( //
+ std::make_tuple(33, 0), //
+ std::make_tuple(34, 0), //
+ std::make_tuple(1000, 0), //
+ std::make_tuple(u32::Highest(), 0), //
+ std::make_tuple(0, 33), //
+ std::make_tuple(0, 34), //
+ std::make_tuple(0, 1000), //
+ std::make_tuple(0, u32::Highest()), //
+ std::make_tuple(33, 33), //
+ std::make_tuple(34, 34), //
+ std::make_tuple(1000, 1000), //
+ std::make_tuple(u32::Highest(), u32::Highest())));
+
+template <typename T>
+std::vector<Case> ExtractBitsCases() {
+ using UT = Number<std::make_unsigned_t<UnwrapNumber<T>>>;
+
+ // If T is signed, fills most significant bits of `val` with 1s
+ auto set_msbs_if_signed = [](T val) {
+ if constexpr (IsSignedIntegral<T>) {
+ T result = T(~0);
+ for (size_t b = 0; val; ++b) {
+ if ((val & 1) == 0) {
+ result = result & ~(1 << b); // Clear bit b
+ }
+ val = val >> 1;
+ }
+ return result;
+ } else {
+ return val;
+ }
+ };
+
+ auto e = T(0b10100011110001011010001111000101);
+ auto f = T(0b01010101010101010101010101010101);
+ auto g = T(0b11111010001111000101101000111100);
+
+ auto r = std::vector<Case>{
+ // args: e, offset, count
+
+ // If count is 0, result is 0
+ C({e, UT(0), UT(0)}, T(0)), //
+ C({e, UT(1), UT(0)}, T(0)), //
+ C({e, UT(2), UT(0)}, T(0)), //
+ C({e, UT(3), UT(0)}, T(0)),
+ // ...
+ C({e, UT(29), UT(0)}, T(0)), //
+ C({e, UT(30), UT(0)}, T(0)), //
+ C({e, UT(31), UT(0)}, T(0)),
+
+ // Extract at offset 0, varying counts
+ C({e, UT(0), UT(1)}, set_msbs_if_signed(T(0b1))), //
+ C({e, UT(0), UT(2)}, T(0b01)), //
+ C({e, UT(0), UT(3)}, set_msbs_if_signed(T(0b101))), //
+ C({e, UT(0), UT(4)}, T(0b0101)), //
+ C({e, UT(0), UT(5)}, T(0b00101)), //
+ C({e, UT(0), UT(6)}, T(0b000101)), //
+ // ...
+ C({e, UT(0), UT(28)}, T(0b0011110001011010001111000101)), //
+ C({e, UT(0), UT(29)}, T(0b00011110001011010001111000101)), //
+ C({e, UT(0), UT(30)}, set_msbs_if_signed(T(0b100011110001011010001111000101))), //
+ C({e, UT(0), UT(31)}, T(0b0100011110001011010001111000101)), //
+ C({e, UT(0), UT(32)}, T(0b10100011110001011010001111000101)), //
+
+ // Extract at varying offsets and counts
+ C({e, UT(0), UT(1)}, set_msbs_if_signed(T(0b1))), //
+ C({e, UT(31), UT(1)}, set_msbs_if_signed(T(0b1))), //
+ C({e, UT(3), UT(5)}, set_msbs_if_signed(T(0b11000))), //
+ C({e, UT(4), UT(7)}, T(0b0111100)), //
+ C({e, UT(10), UT(16)}, set_msbs_if_signed(T(0b1111000101101000))), //
+ C({e, UT(10), UT(22)}, set_msbs_if_signed(T(0b1010001111000101101000))),
+
+ // Vector tests
+ C({Vec(e, f, g), //
+ Val(UT(5)), Val(UT(8))}, //
+ Vec(T(0b00011110), //
+ set_msbs_if_signed(T(0b10101010)), //
+ set_msbs_if_signed(T(0b11010001)))),
+ };
+
+ return r;
+}
+INSTANTIATE_TEST_SUITE_P( //
+ ExtractBits,
+ ResolverConstEvalBuiltinTest,
+ testing::Combine(testing::Values(sem::BuiltinType::kExtractBits),
+ testing::ValuesIn(Concat(ExtractBitsCases<i32>(), //
+ ExtractBitsCases<u32>()))));
+
+using ResolverConstEvalBuiltinTest_ExtractBits_InvalidOffsetAndCount =
+ ResolverTestWithParam<std::tuple<size_t, size_t>>;
+TEST_P(ResolverConstEvalBuiltinTest_ExtractBits_InvalidOffsetAndCount, Test) {
+ auto& p = GetParam();
+ auto* expr = Call(Source{{12, 34}}, sem::str(sem::BuiltinType::kExtractBits), Expr(1_u),
+ Expr(u32(std::get<0>(p))), Expr(u32(std::get<1>(p))));
+ GlobalConst("C", expr);
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "12:34 error: 'offset + 'count' must be less than or equal to the bit width of 'e'");
+}
+INSTANTIATE_TEST_SUITE_P(ExtractBits,
+ ResolverConstEvalBuiltinTest_ExtractBits_InvalidOffsetAndCount,
+ testing::Values( //
+ std::make_tuple(33, 0), //
+ std::make_tuple(34, 0), //
+ std::make_tuple(1000, 0), //
+ std::make_tuple(u32::Highest(), 0), //
+ std::make_tuple(0, 33), //
+ std::make_tuple(0, 34), //
+ std::make_tuple(0, 1000), //
+ std::make_tuple(0, u32::Highest()), //
+ std::make_tuple(33, 33), //
+ std::make_tuple(34, 34), //
+ std::make_tuple(1000, 1000), //
+ std::make_tuple(u32::Highest(), u32::Highest())));
+
+template <typename T>
+std::vector<Case> ReverseBitsCases() {
+ using B = BitValues<T>;
+ return {
+ C({T(0)}, T(0)),
+
+ C({B::Lsh(1, 0)}, B::Lsh(1, 31)), //
+ C({B::Lsh(1, 1)}, B::Lsh(1, 30)), //
+ C({B::Lsh(1, 2)}, B::Lsh(1, 29)), //
+ C({B::Lsh(1, 3)}, B::Lsh(1, 28)), //
+ C({B::Lsh(1, 4)}, B::Lsh(1, 27)), //
+ //...
+ C({B::Lsh(1, 27)}, B::Lsh(1, 4)), //
+ C({B::Lsh(1, 28)}, B::Lsh(1, 3)), //
+ C({B::Lsh(1, 29)}, B::Lsh(1, 2)), //
+ C({B::Lsh(1, 30)}, B::Lsh(1, 1)), //
+ C({B::Lsh(1, 31)}, B::Lsh(1, 0)), //
+
+ C({/**/ T(0b00010001000100010000000000000000)},
+ /* */ T(0b00000000000000001000100010001000)),
+
+ C({/**/ T(0b00011000000110000000000000000000)},
+ /* */ T(0b00000000000000000001100000011000)),
+
+ C({/**/ T(0b00000100000000001111111111111111)},
+ /* */ T(0b11111111111111110000000000100000)),
+
+ C({/**/ T(0b10010101111000110000011111101010)},
+ /* */ T(0b01010111111000001100011110101001)),
+
+ // Vector tests
+ C({/**/ Vec(T(0b00010001000100010000000000000000), //
+ T(0b00011000000110000000000000000000), //
+ T(0b00000000000000001111111111111111))},
+ /* */ Vec(T(0b00000000000000001000100010001000), //
+ T(0b00000000000000000001100000011000), //
+ T(0b11111111111111110000000000000000))),
+ };
+}
+INSTANTIATE_TEST_SUITE_P( //
+ ReverseBits,
+ ResolverConstEvalBuiltinTest,
+ testing::Combine(testing::Values(sem::BuiltinType::kReverseBits),
+ testing::ValuesIn(Concat(ReverseBitsCases<i32>(), //
+ ReverseBitsCases<u32>()))));
+
template <typename T>
std::vector<Case> SaturateCases() {
return {
@@ -842,5 +1268,63 @@
StepCases<f32>(),
StepCases<f16>()))));
+std::vector<Case> QuantizeToF16Cases() {
+ (void)E({Vec(0_f, 0_f)}, ""); // Currently unused, but will be soon.
+ return {
+ C({0_f}, 0_f), //
+ C({-0_f}, -0_f), //
+ C({1_f}, 1_f), //
+ C({-1_f}, -1_f), //
+
+ // 0.00006106496 quantized to 0.000061035156 = 0x1p-14
+ C({0.00006106496_f}, 0.000061035156_f), //
+ C({-0.00006106496_f}, -0.000061035156_f), //
+
+ // 1.0004883 quantized to 1.0 = 0x1p0
+ C({1.0004883_f}, 1.0_f), //
+ C({-1.0004883_f}, -1.0_f), //
+
+ // 8196.0 quantized to 8192.0 = 0x1p13
+ C({8196_f}, 8192_f), //
+ C({-8196_f}, -8192_f), //
+
+ // Value in subnormal f16 range
+ C({0x0.034p-14_f}, 0x0.034p-14_f), //
+ C({-0x0.034p-14_f}, -0x0.034p-14_f), //
+ C({0x0.068p-14_f}, 0x0.068p-14_f), //
+ C({-0x0.068p-14_f}, -0x0.068p-14_f), //
+
+ // 0x0.06b7p-14 quantized to 0x0.068p-14
+ C({0x0.06b7p-14_f}, 0x0.068p-14_f), //
+ C({-0x0.06b7p-14_f}, -0x0.068p-14_f), //
+
+ // Value out of f16 range
+ C({65504.003_f}, 65504_f), //
+ C({-65504.003_f}, -65504_f), //
+ C({0x1.234p56_f}, 65504_f), //
+ C({-0x4.321p65_f}, -65504_f), //
+
+ // Vector tests
+ C({Vec(0_f, -0_f)}, Vec(0_f, -0_f)), //
+ C({Vec(1_f, -1_f)}, Vec(1_f, -1_f)), //
+
+ C({Vec(0.00006106496_f, -0.00006106496_f, 1.0004883_f, -1.0004883_f)},
+ Vec(0.000061035156_f, -0.000061035156_f, 1.0_f, -1.0_f)),
+
+ C({Vec(8196_f, 8192_f, 0x0.034p-14_f)}, Vec(8192_f, 8192_f, 0x0.034p-14_f)),
+
+ C({Vec(0x0.034p-14_f, -0x0.034p-14_f, 0x0.068p-14_f, -0x0.068p-14_f)},
+ Vec(0x0.034p-14_f, -0x0.034p-14_f, 0x0.068p-14_f, -0x0.068p-14_f)),
+
+ C({Vec(65504.003_f, 0x1.234p56_f)}, Vec(65504_f, 65504_f)),
+ C({Vec(-0x1.234p56_f, -65504.003_f)}, Vec(-65504_f, -65504_f)),
+ };
+}
+INSTANTIATE_TEST_SUITE_P( //
+ QuantizeToF16,
+ ResolverConstEvalBuiltinTest,
+ testing::Combine(testing::Values(sem::BuiltinType::kQuantizeToF16),
+ testing::ValuesIn(QuantizeToF16Cases())));
+
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl
index c6d3ad4..ddce1ba 100644
--- a/src/tint/resolver/intrinsic_table.inl
+++ b/src/tint/resolver/intrinsic_table.inl
@@ -2777,12 +2777,12 @@
/* [33] */ 45,
/* [34] */ 5,
/* [35] */ 6,
- /* [36] */ 23,
- /* [37] */ 0,
- /* [38] */ 4,
- /* [39] */ 44,
- /* [40] */ 5,
- /* [41] */ 6,
+ /* [36] */ 44,
+ /* [37] */ 5,
+ /* [38] */ 6,
+ /* [39] */ 23,
+ /* [40] */ 0,
+ /* [41] */ 4,
/* [42] */ 43,
/* [43] */ 5,
/* [44] */ 6,
@@ -2843,34 +2843,34 @@
/* [99] */ 42,
/* [100] */ 3,
/* [101] */ 6,
- /* [102] */ 12,
+ /* [102] */ 13,
/* [103] */ 9,
/* [104] */ 12,
- /* [105] */ 1,
+ /* [105] */ 0,
/* [106] */ 12,
- /* [107] */ 10,
+ /* [107] */ 1,
/* [108] */ 12,
- /* [109] */ 7,
+ /* [109] */ 9,
/* [110] */ 12,
- /* [111] */ 0,
+ /* [111] */ 10,
/* [112] */ 11,
/* [113] */ 0,
/* [114] */ 12,
- /* [115] */ 8,
+ /* [115] */ 7,
/* [116] */ 12,
- /* [117] */ 4,
- /* [118] */ 13,
- /* [119] */ 0,
+ /* [117] */ 8,
+ /* [118] */ 12,
+ /* [119] */ 4,
/* [120] */ 11,
/* [121] */ 4,
/* [122] */ 11,
/* [123] */ 1,
/* [124] */ 11,
/* [125] */ 8,
- /* [126] */ 11,
- /* [127] */ 7,
- /* [128] */ 13,
- /* [129] */ 9,
+ /* [126] */ 13,
+ /* [127] */ 0,
+ /* [128] */ 11,
+ /* [129] */ 7,
/* [130] */ 11,
/* [131] */ 10,
/* [132] */ 11,
@@ -2879,10 +2879,10 @@
/* [135] */ 0,
/* [136] */ 30,
/* [137] */ 0,
- /* [138] */ 31,
- /* [139] */ 0,
- /* [140] */ 13,
- /* [141] */ 1,
+ /* [138] */ 13,
+ /* [139] */ 1,
+ /* [140] */ 31,
+ /* [141] */ 0,
/* [142] */ 32,
/* [143] */ 0,
/* [144] */ 33,
@@ -2949,17 +2949,17 @@
/* [205] */ 10,
/* [206] */ 21,
/* [207] */ 0,
- /* [208] */ 30,
- /* [209] */ 9,
- /* [210] */ 51,
- /* [211] */ 0,
+ /* [208] */ 51,
+ /* [209] */ 0,
+ /* [210] */ 30,
+ /* [211] */ 9,
/* [212] */ 31,
/* [213] */ 9,
/* [214] */ 32,
/* [215] */ 9,
- /* [216] */ 33,
+ /* [216] */ 21,
/* [217] */ 9,
- /* [218] */ 21,
+ /* [218] */ 33,
/* [219] */ 9,
/* [220] */ 21,
/* [221] */ 10,
@@ -3346,12 +3346,12 @@
{
/* [71] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [72] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[212],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [73] */
@@ -3365,23 +3365,23 @@
},
{
/* [75] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[132],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [76] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[132],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [77] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [78] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[214],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [79] */
@@ -3395,53 +3395,53 @@
},
{
/* [81] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [82] */
/* usage */ ParameterUsage::kDdx,
/* matcher indices */ &kMatcherIndices[132],
},
{
- /* [83] */
+ /* [82] */
/* usage */ ParameterUsage::kDdy,
/* matcher indices */ &kMatcherIndices[132],
},
{
+ /* [83] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
+ },
+ {
/* [84] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [85] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [86] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [87] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kArrayIndex,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [88] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [89] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [90] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [91] */
@@ -3451,82 +3451,82 @@
{
/* [92] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
- /* [93] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
- /* [94] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
- /* [95] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[108],
- },
- {
- /* [96] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
- },
- {
- /* [97] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [98] */
- /* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[132],
},
{
- /* [99] */
+ /* [93] */
/* usage */ ParameterUsage::kArrayIndex,
/* matcher indices */ &kMatcherIndices[1],
},
{
- /* [100] */
- /* usage */ ParameterUsage::kLevel,
+ /* [94] */
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[132],
+ },
+ {
+ /* [95] */
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[132],
+ },
+ {
+ /* [96] */
+ /* usage */ ParameterUsage::kComponent,
/* matcher indices */ &kMatcherIndices[12],
},
{
+ /* [97] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[142],
+ },
+ {
+ /* [98] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
+ },
+ {
+ /* [99] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
+ },
+ {
+ /* [100] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[20],
+ },
+ {
/* [101] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [102] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[214],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [103] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [104] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [105] */
- /* usage */ ParameterUsage::kArrayIndex,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [106] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [107] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [108] */
@@ -3556,97 +3556,97 @@
{
/* [113] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [114] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [115] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [116] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [117] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kArrayIndex,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [118] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [119] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [120] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [121] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [122] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [123] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [124] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [125] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[114],
},
{
/* [126] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [127] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [128] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [129] */
- /* usage */ ParameterUsage::kArrayIndex,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [130] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [131] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [132] */
@@ -3676,12 +3676,12 @@
{
/* [137] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [138] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [139] */
@@ -3691,7 +3691,7 @@
{
/* [140] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [141] */
@@ -3700,48 +3700,48 @@
},
{
/* [142] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
- /* [143] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
- /* [144] */
- /* usage */ ParameterUsage::kComponent,
+ /* usage */ ParameterUsage::kLevel,
/* matcher indices */ &kMatcherIndices[12],
},
{
- /* [145] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[142],
+ /* [143] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
- /* [146] */
+ /* [144] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[224],
+ },
+ {
+ /* [145] */
/* usage */ ParameterUsage::kSampler,
/* matcher indices */ &kMatcherIndices[230],
},
{
- /* [147] */
+ /* [146] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
+ },
+ {
+ /* [147] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [148] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[20],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [149] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [150] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[214],
+ /* matcher indices */ &kMatcherIndices[224],
},
{
/* [151] */
@@ -3751,7 +3751,7 @@
{
/* [152] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [153] */
@@ -3765,43 +3765,43 @@
},
{
/* [155] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[12],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [156] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
- },
- {
- /* [157] */
/* usage */ ParameterUsage::kSampler,
/* matcher indices */ &kMatcherIndices[230],
},
{
- /* [158] */
+ /* [157] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
+ },
+ {
+ /* [158] */
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [159] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[114],
},
{
/* [160] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [161] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [162] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [163] */
@@ -3810,68 +3810,68 @@
},
{
/* [164] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[62],
- },
- {
- /* [165] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
- },
- {
- /* [166] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [167] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
- },
- {
- /* [168] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [169] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
- },
- {
- /* [170] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
- },
- {
- /* [171] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [172] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
- /* [173] */
/* usage */ ParameterUsage::kLevel,
/* matcher indices */ &kMatcherIndices[62],
},
{
- /* [174] */
+ /* [165] */
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[12],
+ },
+ {
+ /* [166] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[140],
+ },
+ {
+ /* [167] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
+ },
+ {
+ /* [168] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
+ },
+ {
+ /* [169] */
/* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
+ },
+ {
+ /* [170] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[232],
+ },
+ {
+ /* [171] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[231],
+ },
+ {
+ /* [172] */
+ /* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[108],
},
{
+ /* [173] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [174] */
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[62],
+ },
+ {
/* [175] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [176] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [177] */
@@ -3880,38 +3880,38 @@
},
{
/* [178] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [179] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
- },
- {
- /* [180] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
- },
- {
- /* [181] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
- },
- {
- /* [182] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
- },
- {
- /* [183] */
/* usage */ ParameterUsage::kDepthRef,
/* matcher indices */ &kMatcherIndices[62],
},
{
- /* [184] */
+ /* [179] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[128],
+ },
+ {
+ /* [180] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[232],
+ },
+ {
+ /* [181] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
+ },
+ {
+ /* [182] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
+ },
+ {
+ /* [183] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [184] */
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[12],
},
{
/* [185] */
@@ -3955,18 +3955,18 @@
},
{
/* [193] */
- /* usage */ ParameterUsage::kBias,
+ /* usage */ ParameterUsage::kLevel,
/* matcher indices */ &kMatcherIndices[62],
},
{
/* [194] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [195] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[214],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [196] */
@@ -3976,47 +3976,47 @@
{
/* [197] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [198] */
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[108],
+ },
+ {
+ /* [199] */
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[108],
+ },
+ {
+ /* [200] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[232],
+ },
+ {
+ /* [201] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[231],
+ },
+ {
+ /* [202] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
+ },
+ {
+ /* [203] */
/* usage */ ParameterUsage::kArrayIndex,
/* matcher indices */ &kMatcherIndices[1],
},
{
- /* [199] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
- },
- {
- /* [200] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[12],
- },
- {
- /* [201] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[150],
- },
- {
- /* [202] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [203] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
/* [204] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[20],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [205] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [206] */
@@ -4026,7 +4026,7 @@
{
/* [207] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [208] */
@@ -4035,13 +4035,13 @@
},
{
/* [209] */
- /* usage */ ParameterUsage::kLevel,
+ /* usage */ ParameterUsage::kBias,
/* matcher indices */ &kMatcherIndices[62],
},
{
/* [210] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [211] */
@@ -4051,22 +4051,22 @@
{
/* [212] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [213] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [214] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[108],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[12],
},
{
/* [215] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [216] */
@@ -4080,68 +4080,68 @@
},
{
/* [218] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [219] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [220] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [221] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [222] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [223] */
- /* usage */ ParameterUsage::kArrayIndex,
+ /* usage */ ParameterUsage::kLevel,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [224] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [225] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[12],
},
{
/* [226] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [227] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
+ },
+ {
+ /* [228] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[132],
},
{
- /* [228] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[62],
- },
- {
/* [229] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[20],
},
{
/* [230] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[214],
+ /* matcher indices */ &kMatcherIndices[224],
},
{
/* [231] */
@@ -4151,7 +4151,7 @@
{
/* [232] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [233] */
@@ -4166,7 +4166,7 @@
{
/* [235] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [236] */
@@ -4176,7 +4176,7 @@
{
/* [237] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [238] */
@@ -4185,18 +4185,18 @@
},
{
/* [239] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [240] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [241] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [242] */
@@ -4205,18 +4205,18 @@
},
{
/* [243] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [244] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[12],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [245] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [246] */
@@ -4226,7 +4226,7 @@
{
/* [247] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [248] */
@@ -4266,7 +4266,7 @@
{
/* [255] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [256] */
@@ -4276,7 +4276,7 @@
{
/* [257] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [258] */
@@ -4291,89 +4291,89 @@
{
/* [260] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [261] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [262] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [263] */
- /* usage */ ParameterUsage::kDepthRef,
+ /* usage */ ParameterUsage::kLevel,
/* matcher indices */ &kMatcherIndices[62],
},
{
/* [264] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[114],
},
{
/* [265] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[12],
- },
- {
- /* [266] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[142],
- },
- {
- /* [267] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [268] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
- },
- {
- /* [269] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[20],
- },
- {
- /* [270] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
- },
- {
- /* [271] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [272] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
- /* [273] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
- /* [274] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
- /* [275] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[234],
},
{
- /* [276] */
+ /* [266] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
+ },
+ {
+ /* [267] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
+ },
+ {
+ /* [268] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [269] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
+ },
+ {
+ /* [270] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[234],
+ },
+ {
+ /* [271] */
/* usage */ ParameterUsage::kSampler,
/* matcher indices */ &kMatcherIndices[231],
},
{
+ /* [272] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
+ },
+ {
+ /* [273] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [274] */
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[62],
+ },
+ {
+ /* [275] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[214],
+ },
+ {
+ /* [276] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
+ },
+ {
/* [277] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[132],
@@ -4385,63 +4385,63 @@
},
{
/* [279] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [280] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[222],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [281] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [282] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [283] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[102],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [284] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[102],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [285] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[12],
},
{
/* [286] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[150],
+ },
+ {
+ /* [287] */
/* usage */ ParameterUsage::kSampler,
/* matcher indices */ &kMatcherIndices[230],
},
{
- /* [287] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
/* [288] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [289] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[12],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[20],
},
{
/* [290] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[212],
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [291] */
@@ -4451,22 +4451,22 @@
{
/* [292] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [293] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [294] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [295] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[214],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [296] */
@@ -4480,18 +4480,18 @@
},
{
/* [298] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [299] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[212],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [300] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [301] */
@@ -4500,33 +4500,33 @@
},
{
/* [302] */
- /* usage */ ParameterUsage::kLevel,
+ /* usage */ ParameterUsage::kDepthRef,
/* matcher indices */ &kMatcherIndices[62],
},
{
/* [303] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [304] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [305] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [306] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [307] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[212],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [308] */
@@ -4536,57 +4536,57 @@
{
/* [309] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [310] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [311] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [312] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [313] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [314] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[114],
+ },
+ {
+ /* [315] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[233],
+ },
+ {
+ /* [316] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[231],
+ },
+ {
+ /* [317] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
+ },
+ {
+ /* [318] */
/* usage */ ParameterUsage::kDepthRef,
/* matcher indices */ &kMatcherIndices[62],
},
{
- /* [315] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
- },
- {
- /* [316] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
- },
- {
- /* [317] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
- },
- {
- /* [318] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
- },
- {
/* [319] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
+ /* matcher indices */ &kMatcherIndices[224],
},
{
/* [320] */
@@ -4596,17 +4596,17 @@
{
/* [321] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [322] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[108],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [323] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[224],
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [324] */
@@ -4616,12 +4616,12 @@
{
/* [325] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [326] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [327] */
@@ -4631,7 +4631,7 @@
{
/* [328] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [329] */
@@ -4640,13 +4640,13 @@
},
{
/* [330] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [331] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [332] */
@@ -4656,7 +4656,7 @@
{
/* [333] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [334] */
@@ -4666,7 +4666,7 @@
{
/* [335] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [336] */
@@ -4676,117 +4676,117 @@
{
/* [337] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [338] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [339] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
- },
- {
- /* [340] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [341] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
- },
- {
- /* [342] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [343] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
- },
- {
- /* [344] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [345] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
- },
- {
- /* [346] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[126],
- },
- {
- /* [347] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
- },
- {
- /* [348] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [349] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
- },
- {
- /* [350] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [351] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[12],
- },
- {
- /* [352] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
- },
- {
- /* [353] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [354] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
- /* [355] */
/* usage */ ParameterUsage::kX,
/* matcher indices */ &kMatcherIndices[1],
},
{
- /* [356] */
+ /* [340] */
/* usage */ ParameterUsage::kY,
/* matcher indices */ &kMatcherIndices[1],
},
{
- /* [357] */
+ /* [341] */
/* usage */ ParameterUsage::kZ,
/* matcher indices */ &kMatcherIndices[1],
},
{
- /* [358] */
+ /* [342] */
/* usage */ ParameterUsage::kW,
/* matcher indices */ &kMatcherIndices[1],
},
{
+ /* [343] */
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[12],
+ },
+ {
+ /* [344] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[140],
+ },
+ {
+ /* [345] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
+ },
+ {
+ /* [346] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
+ },
+ {
+ /* [347] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[72],
+ },
+ {
+ /* [348] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[112],
+ },
+ {
+ /* [349] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[12],
+ },
+ {
+ /* [350] */
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[102],
+ },
+ {
+ /* [351] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[233],
+ },
+ {
+ /* [352] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
+ },
+ {
+ /* [353] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
+ },
+ {
+ /* [354] */
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [355] */
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[12],
+ },
+ {
+ /* [356] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[148],
+ },
+ {
+ /* [357] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
+ },
+ {
+ /* [358] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
+ },
+ {
/* [359] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
+ /* matcher indices */ &kMatcherIndices[54],
},
{
/* [360] */
@@ -4800,53 +4800,53 @@
},
{
/* [362] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[20],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[152],
},
{
/* [363] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[39],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [364] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [365] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[12],
- },
- {
- /* [366] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[156],
- },
- {
- /* [367] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[12],
- },
- {
- /* [368] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
- },
- {
- /* [369] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [370] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[132],
},
{
+ /* [366] */
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[62],
+ },
+ {
+ /* [367] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[142],
+ },
+ {
+ /* [368] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
+ },
+ {
+ /* [369] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[20],
+ },
+ {
+ /* [370] */
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[67],
+ },
+ {
/* [371] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [372] */
@@ -4856,57 +4856,57 @@
{
/* [373] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [374] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[62],
- },
- {
- /* [375] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[212],
- },
- {
- /* [376] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [377] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
- },
- {
- /* [378] */
/* usage */ ParameterUsage::kBias,
/* matcher indices */ &kMatcherIndices[62],
},
{
+ /* [375] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [376] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [377] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [378] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
/* [379] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[222],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [380] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [381] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [382] */
- /* usage */ ParameterUsage::kLevel,
+ /* usage */ ParameterUsage::kDepthRef,
/* matcher indices */ &kMatcherIndices[62],
},
{
/* [383] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [384] */
@@ -4916,7 +4916,7 @@
{
/* [385] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [386] */
@@ -4926,82 +4926,82 @@
{
/* [387] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [388] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [389] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [390] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [391] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[222],
+ /* matcher indices */ &kMatcherIndices[36],
},
{
/* [392] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [393] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[12],
},
{
/* [394] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [395] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [396] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [397] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[12],
},
{
/* [398] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[20],
},
{
/* [399] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [400] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [401] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [402] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [403] */
@@ -5026,7 +5026,7 @@
{
/* [407] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [408] */
@@ -5036,72 +5036,72 @@
{
/* [409] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [410] */
- /* usage */ ParameterUsage::kLevel,
+ /* usage */ ParameterUsage::kArrayIndex,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [411] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [412] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [413] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [414] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [415] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[72],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [416] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [417] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[12],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [418] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[128],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [419] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [420] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [421] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [422] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [423] */
@@ -5146,62 +5146,62 @@
{
/* [431] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[54],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [432] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [433] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[12],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [434] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[152],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [435] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[142],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [436] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[122],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [437] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[20],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [438] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[67],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [439] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [440] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [441] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [442] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [443] */
@@ -5211,7 +5211,7 @@
{
/* [444] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [445] */
@@ -5220,118 +5220,118 @@
},
{
/* [446] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [447] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [448] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[122],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [449] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[20],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [450] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [451] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [452] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [453] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[112],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [454] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[112],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [455] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[112],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [456] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [457] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [458] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [459] */
- /* usage */ ParameterUsage::kX,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [460] */
- /* usage */ ParameterUsage::kY,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [461] */
- /* usage */ ParameterUsage::kZw,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [462] */
- /* usage */ ParameterUsage::kX,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [463] */
- /* usage */ ParameterUsage::kYz,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [464] */
- /* usage */ ParameterUsage::kW,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [465] */
- /* usage */ ParameterUsage::kXy,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [466] */
- /* usage */ ParameterUsage::kZ,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [467] */
- /* usage */ ParameterUsage::kW,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [468] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [469] */
@@ -5341,37 +5341,37 @@
{
/* [470] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [471] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [472] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [473] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [474] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [475] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [476] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [477] */
@@ -5421,7 +5421,7 @@
{
/* [486] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [487] */
@@ -5431,102 +5431,102 @@
{
/* [488] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [489] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[222],
+ /* matcher indices */ &kMatcherIndices[51],
},
{
/* [490] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [491] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[152],
},
{
/* [492] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[144],
+ },
+ {
+ /* [493] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[106],
+ },
+ {
+ /* [494] */
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[20],
+ },
+ {
+ /* [495] */
/* usage */ ParameterUsage::kX,
/* matcher indices */ &kMatcherIndices[1],
},
{
- /* [493] */
+ /* [496] */
/* usage */ ParameterUsage::kY,
/* matcher indices */ &kMatcherIndices[1],
},
{
- /* [494] */
+ /* [497] */
/* usage */ ParameterUsage::kZ,
/* matcher indices */ &kMatcherIndices[1],
},
{
- /* [495] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[216],
- },
- {
- /* [496] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [497] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
- },
- {
/* [498] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[212],
+ /* usage */ ParameterUsage::kXy,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [499] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* usage */ ParameterUsage::kZ,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [500] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
+ /* usage */ ParameterUsage::kW,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [501] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[208],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [502] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
+ /* usage */ ParameterUsage::kYz,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [503] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kW,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [504] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [505] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* usage */ ParameterUsage::kY,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [506] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* usage */ ParameterUsage::kZw,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [507] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
+ /* matcher indices */ &kMatcherIndices[236],
},
{
/* [508] */
@@ -5536,179 +5536,179 @@
{
/* [509] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [510] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [511] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
- },
- {
- /* [512] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
- },
- {
- /* [513] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [514] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
- },
- {
- /* [515] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
- },
- {
- /* [516] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [517] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [518] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [519] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [520] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [521] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [522] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [523] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [524] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [525] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [526] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [527] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [528] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
- },
- {
- /* [529] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [530] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [531] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
- },
- {
- /* [532] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [533] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
- },
- {
- /* [534] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[236],
- },
- {
- /* [535] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[230],
- },
- {
- /* [536] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[132],
- },
- {
- /* [537] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[212],
},
{
- /* [538] */
+ /* [511] */
/* usage */ ParameterUsage::kSampler,
/* matcher indices */ &kMatcherIndices[230],
},
{
- /* [539] */
+ /* [512] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[132],
},
{
- /* [540] */
+ /* [513] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[236],
},
{
- /* [541] */
+ /* [514] */
/* usage */ ParameterUsage::kSampler,
/* matcher indices */ &kMatcherIndices[230],
},
{
- /* [542] */
+ /* [515] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[132],
},
{
- /* [543] */
+ /* [516] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[99],
},
{
+ /* [517] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [518] */
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[102],
+ },
+ {
+ /* [519] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[75],
+ },
+ {
+ /* [520] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[112],
+ },
+ {
+ /* [521] */
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[102],
+ },
+ {
+ /* [522] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[66],
+ },
+ {
+ /* [523] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[104],
+ },
+ {
+ /* [524] */
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[102],
+ },
+ {
+ /* [525] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[63],
+ },
+ {
+ /* [526] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [527] */
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[152],
+ },
+ {
+ /* [528] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[57],
+ },
+ {
+ /* [529] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[112],
+ },
+ {
+ /* [530] */
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[152],
+ },
+ {
+ /* [531] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [532] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [533] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [534] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
+ },
+ {
+ /* [535] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [536] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [537] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [538] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [539] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [540] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [541] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [542] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [543] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[48],
+ },
+ {
/* [544] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[1],
@@ -5716,267 +5716,267 @@
{
/* [545] */
/* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [546] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[75],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [547] */
- /* usage */ ParameterUsage::kCoords,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[112],
},
{
/* [548] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[128],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [549] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [550] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [551] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
- },
- {
- /* [552] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [553] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [554] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
- },
- {
- /* [555] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[66],
- },
- {
- /* [556] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[110],
- },
- {
- /* [557] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[128],
- },
- {
- /* [558] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[63],
- },
- {
- /* [559] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [560] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[152],
- },
- {
- /* [561] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[57],
- },
- {
- /* [562] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[112],
- },
- {
- /* [563] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[152],
- },
- {
- /* [564] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[51],
- },
- {
- /* [565] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[110],
- },
- {
- /* [566] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[152],
- },
- {
- /* [567] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[48],
- },
- {
- /* [568] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [569] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[156],
- },
- {
- /* [570] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[237],
- },
- {
- /* [571] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[112],
- },
- {
- /* [572] */
- /* usage */ ParameterUsage::kSampleIndex,
- /* matcher indices */ &kMatcherIndices[12],
- },
- {
- /* [573] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [574] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [575] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [576] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [577] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [578] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
- /* [579] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[42],
},
{
- /* [580] */
+ /* [550] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[112],
},
{
- /* [581] */
+ /* [551] */
/* usage */ ParameterUsage::kValue,
/* matcher indices */ &kMatcherIndices[156],
},
{
- /* [582] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
+ /* [552] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
- /* [583] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[112],
+ /* [553] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
- /* [584] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[12],
+ /* [554] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[41],
},
{
- /* [585] */
+ /* [555] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [556] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [557] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[41],
+ },
+ {
+ /* [558] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [559] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [560] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[39],
+ },
+ {
+ /* [561] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
+ },
+ {
+ /* [562] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
+ },
+ {
+ /* [563] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
+ },
+ {
+ /* [564] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[33],
},
{
- /* [586] */
+ /* [565] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[114],
},
{
- /* [587] */
+ /* [566] */
/* usage */ ParameterUsage::kValue,
/* matcher indices */ &kMatcherIndices[156],
},
{
- /* [588] */
+ /* [567] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[136],
},
{
- /* [589] */
+ /* [568] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[12],
},
{
- /* [590] */
+ /* [569] */
/* usage */ ParameterUsage::kLevel,
/* matcher indices */ &kMatcherIndices[20],
},
{
+ /* [570] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[140],
+ },
+ {
+ /* [571] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
+ },
+ {
+ /* [572] */
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[20],
+ },
+ {
+ /* [573] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[233],
+ },
+ {
+ /* [574] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[230],
+ },
+ {
+ /* [575] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
+ },
+ {
+ /* [576] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[126],
+ },
+ {
+ /* [577] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[126],
+ },
+ {
+ /* [578] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[126],
+ },
+ {
+ /* [579] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [580] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [581] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [582] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [583] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [584] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [585] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[235],
+ },
+ {
+ /* [586] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[112],
+ },
+ {
+ /* [587] */
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[12],
+ },
+ {
+ /* [588] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[154],
+ },
+ {
+ /* [589] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
+ },
+ {
+ /* [590] */
+ /* usage */ ParameterUsage::kSampleIndex,
+ /* matcher indices */ &kMatcherIndices[20],
+ },
+ {
/* [591] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[154],
+ /* matcher indices */ &kMatcherIndices[237],
},
{
/* [592] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[122],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [593] */
/* usage */ ParameterUsage::kSampleIndex,
- /* matcher indices */ &kMatcherIndices[20],
+ /* matcher indices */ &kMatcherIndices[12],
},
{
/* [594] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [595] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[104],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [596] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[20],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [597] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[10],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [598] */
@@ -5986,27 +5986,27 @@
{
/* [599] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[69],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [600] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[10],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [601] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[236],
},
{
/* [602] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [603] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [604] */
@@ -6015,33 +6015,33 @@
},
{
/* [605] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [606] */
- /* usage */ ParameterUsage::kLevel,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [607] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [608] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[4],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [609] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[236],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [610] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [611] */
@@ -6056,12 +6056,12 @@
{
/* [613] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [614] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[22],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [615] */
@@ -6076,12 +6076,12 @@
{
/* [617] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [618] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [619] */
@@ -6096,22 +6096,22 @@
{
/* [621] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [622] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [623] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[136],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [624] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[12],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [625] */
@@ -6121,12 +6121,12 @@
{
/* [626] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [627] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[136],
},
{
/* [628] */
@@ -6136,17 +6136,17 @@
{
/* [629] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [630] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[90],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [631] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[142],
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [632] */
@@ -6156,17 +6156,17 @@
{
/* [633] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [634] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [635] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [636] */
@@ -6176,7 +6176,7 @@
{
/* [637] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [638] */
@@ -6186,7 +6186,7 @@
{
/* [639] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
+ /* matcher indices */ &kMatcherIndices[144],
},
{
/* [640] */
@@ -6196,17 +6196,17 @@
{
/* [641] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[10],
},
{
/* [642] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[10],
},
{
/* [643] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[150],
+ /* matcher indices */ &kMatcherIndices[148],
},
{
/* [644] */
@@ -6216,7 +6216,7 @@
{
/* [645] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [646] */
@@ -6225,38 +6225,38 @@
},
{
/* [647] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[150],
},
{
/* [648] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[12],
},
{
/* [649] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [650] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [651] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [652] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [653] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [654] */
@@ -6271,12 +6271,12 @@
{
/* [656] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [657] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [658] */
@@ -6286,21 +6286,21 @@
{
/* [659] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[10],
},
{
/* [660] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[10],
},
{
/* [661] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [662] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kLevel,
/* matcher indices */ &kMatcherIndices[1],
},
{
@@ -6311,57 +6311,57 @@
{
/* [664] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [665] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [666] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [667] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [668] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [669] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [670] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [671] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [672] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [673] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [674] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [675] */
@@ -6381,92 +6381,92 @@
{
/* [678] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [679] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [680] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [681] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[10],
},
{
/* [682] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [683] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[10],
},
{
/* [684] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [685] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [686] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[10],
},
{
/* [687] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [688] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[90],
},
{
/* [689] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [690] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [691] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[18],
},
{
/* [692] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[22],
},
{
/* [693] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [694] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [695] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [696] */
@@ -6476,42 +6476,42 @@
{
/* [697] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [698] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [699] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [700] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [701] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[10],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [702] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[10],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [703] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [704] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [705] */
@@ -6521,7 +6521,7 @@
{
/* [706] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [707] */
@@ -6531,47 +6531,47 @@
{
/* [708] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [709] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [710] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [711] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [712] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [713] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [714] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [715] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [716] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [717] */
@@ -6596,22 +6596,22 @@
{
/* [721] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [722] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [723] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [724] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [725] */
@@ -6621,47 +6621,47 @@
{
/* [726] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [727] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [728] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
+ /* usage */ ParameterUsage::kYz,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [729] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [730] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [731] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [732] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [733] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [734] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [735] */
@@ -6681,7 +6681,7 @@
{
/* [738] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[93],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [739] */
@@ -6691,27 +6691,27 @@
{
/* [740] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [741] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [742] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[93],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [743] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [744] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [745] */
@@ -6741,7 +6741,7 @@
{
/* [750] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [751] */
@@ -6751,16 +6751,16 @@
{
/* [752] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[93],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [753] */
- /* usage */ ParameterUsage::kX,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [754] */
- /* usage */ ParameterUsage::kY,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
{
@@ -6771,7 +6771,7 @@
{
/* [756] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [757] */
@@ -6781,47 +6781,47 @@
{
/* [758] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [759] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[10],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [760] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[10],
+ /* matcher indices */ &kMatcherIndices[93],
},
{
/* [761] */
- /* usage */ ParameterUsage::kXy,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [762] */
- /* usage */ ParameterUsage::kZ,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [763] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [764] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [765] */
- /* usage */ ParameterUsage::kX,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [766] */
- /* usage */ ParameterUsage::kYz,
- /* matcher indices */ &kMatcherIndices[112],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [767] */
@@ -6846,42 +6846,42 @@
{
/* [771] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [772] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [773] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [774] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[93],
},
{
/* [775] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [776] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [777] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [778] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [779] */
@@ -6891,16 +6891,16 @@
{
/* [780] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[93],
},
{
/* [781] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kX,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [782] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kY,
/* matcher indices */ &kMatcherIndices[1],
},
{
@@ -6910,38 +6910,38 @@
},
{
/* [784] */
+ /* usage */ ParameterUsage::kZ,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [785] */
+ /* usage */ ParameterUsage::kXy,
+ /* matcher indices */ &kMatcherIndices[112],
+ },
+ {
+ /* [786] */
/* usage */ ParameterUsage::kZw,
/* matcher indices */ &kMatcherIndices[112],
},
{
- /* [785] */
+ /* [787] */
/* usage */ ParameterUsage::kXyz,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
- /* [786] */
+ /* [788] */
/* usage */ ParameterUsage::kW,
/* matcher indices */ &kMatcherIndices[1],
},
{
- /* [787] */
+ /* [789] */
/* usage */ ParameterUsage::kX,
/* matcher indices */ &kMatcherIndices[1],
},
{
- /* [788] */
- /* usage */ ParameterUsage::kZyw,
- /* matcher indices */ &kMatcherIndices[110],
- },
- {
- /* [789] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
- },
- {
/* [790] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kZyw,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [791] */
@@ -6956,22 +6956,22 @@
{
/* [793] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [794] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [795] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [796] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [797] */
@@ -6981,47 +6981,47 @@
{
/* [798] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[10],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [799] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[10],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [800] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [801] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [802] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [803] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [804] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[10],
},
{
/* [805] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [806] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [807] */
@@ -7031,82 +7031,82 @@
{
/* [808] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
+ /* matcher indices */ &kMatcherIndices[154],
},
{
/* [809] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [810] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [811] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [812] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[150],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [813] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
+ /* matcher indices */ &kMatcherIndices[150],
},
{
/* [814] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* matcher indices */ &kMatcherIndices[148],
},
{
/* [815] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[142],
+ /* matcher indices */ &kMatcherIndices[144],
},
{
/* [816] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [817] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[136],
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [818] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[45],
+ /* matcher indices */ &kMatcherIndices[136],
},
{
/* [819] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [820] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [821] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[150],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [822] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[142],
+ /* matcher indices */ &kMatcherIndices[150],
},
{
/* [823] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[236],
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [824] */
@@ -7181,7 +7181,7 @@
{
/* [838] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[138],
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [839] */
@@ -7191,7 +7191,7 @@
{
/* [840] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
+ /* matcher indices */ &kMatcherIndices[162],
},
{
/* [841] */
@@ -7216,42 +7216,42 @@
{
/* [845] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [846] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [847] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[10],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [848] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[10],
},
{
/* [849] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [850] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [851] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [852] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[162],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [853] */
@@ -7261,22 +7261,22 @@
{
/* [854] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [855] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [856] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [857] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [858] */
@@ -7286,12 +7286,12 @@
{
/* [859] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [860] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[236],
},
{
/* [861] */
@@ -7331,27 +7331,27 @@
{
/* [868] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [869] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [870] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [871] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [872] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [873] */
@@ -7376,47 +7376,47 @@
{
/* [877] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [878] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [879] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [880] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [881] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[102],
},
{
/* [882] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[132],
+ /* matcher indices */ &kMatcherIndices[102],
},
{
/* [883] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [884] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [885] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [886] */
@@ -7426,82 +7426,82 @@
{
/* [887] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [888] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [889] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [890] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [891] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [892] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [893] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [894] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [895] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [896] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [897] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [898] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [899] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [900] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [901] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [902] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [903] */
@@ -7561,27 +7561,27 @@
{
/* [914] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [915] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [916] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [917] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [918] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [919] */
@@ -7591,72 +7591,72 @@
{
/* [920] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [921] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [922] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [923] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [924] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [925] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[60],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [926] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [927] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[14],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [928] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [929] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [930] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [931] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [932] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [933] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[4],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [934] */
@@ -7666,72 +7666,72 @@
{
/* [935] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[226],
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [936] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[95],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [937] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[226],
},
{
/* [938] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[220],
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [939] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [940] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [941] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[218],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [942] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[6],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [943] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [944] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[6],
},
{
/* [945] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [946] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [947] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [948] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[112],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [949] */
@@ -7741,17 +7741,17 @@
{
/* [950] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [951] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[122],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [952] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[122],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [953] */
@@ -7771,77 +7771,77 @@
{
/* [956] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[206],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [957] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [958] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[206],
},
{
/* [959] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [960] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [961] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [962] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [963] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [964] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [965] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [966] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[104],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [967] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[204],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [968] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [969] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[204],
},
{
/* [970] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [971] */
@@ -7851,227 +7851,237 @@
{
/* [972] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [973] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [974] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [975] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [976] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [977] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [978] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[140],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [979] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[140],
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [980] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[140],
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [981] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[140],
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [982] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[202],
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [983] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[160],
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [984] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [985] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[160],
},
{
/* [986] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[164],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [987] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[166],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [988] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[154],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[164],
},
{
/* [989] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[168],
+ /* matcher indices */ &kMatcherIndices[166],
},
{
/* [990] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [991] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[168],
},
{
/* [992] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[170],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [993] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[174],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [994] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[170],
},
{
/* [995] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[176],
+ /* matcher indices */ &kMatcherIndices[174],
},
{
/* [996] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [997] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[176],
},
{
/* [998] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[178],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [999] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[180],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [1000] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[200],
+ /* matcher indices */ &kMatcherIndices[178],
},
{
/* [1001] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[182],
+ /* matcher indices */ &kMatcherIndices[180],
},
{
/* [1002] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[200],
},
{
/* [1003] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[182],
},
{
/* [1004] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[184],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [1005] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[186],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [1006] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[184],
},
{
/* [1007] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[188],
+ /* matcher indices */ &kMatcherIndices[186],
},
{
/* [1008] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [1009] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[188],
},
{
/* [1010] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[190],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [1011] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[192],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [1012] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[196],
+ /* matcher indices */ &kMatcherIndices[190],
},
{
/* [1013] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [1014] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [1015] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [1016] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[140],
+ /* matcher indices */ &kMatcherIndices[60],
+ },
+ {
+ /* [1017] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[39],
+ },
+ {
+ /* [1018] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
};
@@ -8189,22 +8199,22 @@
{
/* [22] */
/* name */ "T",
- /* matcher index */ 65,
+ /* matcher index */ 69,
},
{
/* [23] */
/* name */ "T",
- /* matcher index */ 69,
+ /* matcher index */ 63,
},
{
/* [24] */
/* name */ "T",
- /* matcher index */ 63,
+ /* matcher index */ 70,
},
{
/* [25] */
/* name */ "T",
- /* matcher index */ 70,
+ /* matcher index */ 65,
},
{
/* [26] */
@@ -8244,12 +8254,12 @@
{
/* [33] */
/* name */ "T",
- /* matcher index */ kNoMatcher,
+ /* matcher index */ 56,
},
{
/* [34] */
/* name */ "T",
- /* matcher index */ 56,
+ /* matcher index */ kNoMatcher,
},
{
/* [35] */
@@ -8341,7 +8351,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[623],
+ /* parameters */ &kParameters[627],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8365,7 +8375,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[627],
+ /* parameters */ &kParameters[631],
/* return matcher indices */ &kMatcherIndices[124],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8389,7 +8399,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[631],
+ /* parameters */ &kParameters[635],
/* return matcher indices */ &kMatcherIndices[124],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8402,7 +8412,7 @@
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[836],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8413,8 +8423,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[635],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* parameters */ &kParameters[639],
+ /* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8437,7 +8447,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[639],
+ /* parameters */ &kParameters[643],
/* return matcher indices */ &kMatcherIndices[124],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8461,7 +8471,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[643],
+ /* parameters */ &kParameters[647],
/* return matcher indices */ &kMatcherIndices[124],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8497,7 +8507,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[3],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[687],
+ /* parameters */ &kParameters[653],
/* return matcher indices */ &kMatcherIndices[124],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8521,7 +8531,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[3],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[653],
+ /* parameters */ &kParameters[657],
/* return matcher indices */ &kMatcherIndices[124],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8545,7 +8555,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[3],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[657],
+ /* parameters */ &kParameters[661],
/* return matcher indices */ &kMatcherIndices[124],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8569,7 +8579,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[3],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[605],
+ /* parameters */ &kParameters[665],
/* return matcher indices */ &kMatcherIndices[124],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8630,7 +8640,7 @@
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[3],
/* parameters */ &kParameters[824],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8641,7 +8651,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[823],
+ /* parameters */ &kParameters[860],
/* return matcher indices */ &kMatcherIndices[124],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8653,8 +8663,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[299],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[295],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8665,8 +8675,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[290],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[190],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8677,8 +8687,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[230],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[160],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8689,8 +8699,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[102],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[72],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8701,8 +8711,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[371],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[307],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8713,8 +8723,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[170],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[260],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8725,8 +8735,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[379],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[323],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8737,8 +8747,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[205],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[230],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8749,7 +8759,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[3],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[387],
+ /* parameters */ &kParameters[443],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8761,7 +8771,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[3],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[215],
+ /* parameters */ &kParameters[220],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8773,7 +8783,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[240],
+ /* parameters */ &kParameters[210],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8785,7 +8795,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[96],
+ /* parameters */ &kParameters[138],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8797,7 +8807,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[3],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[407],
+ /* parameters */ &kParameters[351],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8809,7 +8819,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[285],
+ /* parameters */ &kParameters[180],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8821,8 +8831,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[534],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[507],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kIsDeprecated),
/* const eval */ nullptr,
},
@@ -8833,8 +8843,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[1019],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -8845,8 +8855,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[968],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[970],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -8857,8 +8867,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[969],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[971],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecSplat,
},
@@ -8869,8 +8879,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[355],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[339],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitS,
},
@@ -8881,8 +8891,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[465],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[498],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
},
@@ -8893,8 +8903,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[462],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[501],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
},
@@ -8905,8 +8915,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[459],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[504],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
},
@@ -8917,8 +8927,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[783],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[785],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
},
@@ -8929,8 +8939,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[785],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[787],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
},
@@ -8941,8 +8951,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[787],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[789],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
},
@@ -8953,8 +8963,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[979],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -8965,7 +8975,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[978],
+ /* parameters */ &kParameters[980],
/* return matcher indices */ &kMatcherIndices[146],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -8977,7 +8987,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[979],
+ /* parameters */ &kParameters[981],
/* return matcher indices */ &kMatcherIndices[152],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -8989,7 +8999,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[980],
+ /* parameters */ &kParameters[982],
/* return matcher indices */ &kMatcherIndices[156],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9001,7 +9011,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[20],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[981],
+ /* parameters */ &kParameters[983],
/* return matcher indices */ &kMatcherIndices[158],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9013,8 +9023,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[501],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[462],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9025,8 +9035,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[498],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[465],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9037,8 +9047,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[307],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[435],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9049,8 +9059,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[295],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[303],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9061,8 +9071,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[195],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[275],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9073,8 +9083,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[495],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[468],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9085,8 +9095,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[319],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[311],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9097,8 +9107,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[489],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[471],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9109,8 +9119,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[323],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[319],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -9121,7 +9131,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[486],
+ /* parameters */ &kParameters[474],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -9133,7 +9143,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[335],
+ /* parameters */ &kParameters[327],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -9145,7 +9155,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[347],
+ /* parameters */ &kParameters[331],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -9157,7 +9167,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[165],
+ /* parameters */ &kParameters[235],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -9169,7 +9179,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[468],
+ /* parameters */ &kParameters[486],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -9181,157 +9191,109 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[395],
+ /* parameters */ &kParameters[335],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [72] */
- /* num parameters */ 4,
- /* num template types */ 2,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[367],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[516],
+ /* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [73] */
- /* num parameters */ 5,
- /* num template types */ 2,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[155],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[519],
+ /* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [74] */
- /* num parameters */ 5,
- /* num template types */ 3,
+ /* num parameters */ 4,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[265],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[347],
+ /* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [75] */
- /* num parameters */ 6,
- /* num template types */ 3,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[144],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[522],
+ /* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [76] */
- /* num parameters */ 4,
- /* num template types */ 2,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[351],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[525],
+ /* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [77] */
- /* num parameters */ 5,
- /* num template types */ 3,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[200],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[528],
+ /* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [78] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 4,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[531],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[359],
+ /* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [79] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[343],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[489],
+ /* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [80] */
- /* num parameters */ 4,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[339],
- /* return matcher indices */ &kMatcherIndices[128],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [81] */
- /* num parameters */ 5,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[175],
- /* return matcher indices */ &kMatcherIndices[128],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [82] */
- /* num parameters */ 3,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[507],
- /* return matcher indices */ &kMatcherIndices[128],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [83] */
- /* num parameters */ 4,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[331],
- /* return matcher indices */ &kMatcherIndices[128],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [84] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -9343,83 +9305,35 @@
/* const eval */ nullptr,
},
{
- /* [85] */
+ /* [81] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[546],
+ /* parameters */ &kParameters[549],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [86] */
+ /* [82] */
/* num parameters */ 4,
/* num template types */ 2,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[415],
+ /* parameters */ &kParameters[391],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [87] */
+ /* [83] */
/* num parameters */ 3,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[1],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[555],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [88] */
- /* num parameters */ 3,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[1],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[558],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [89] */
- /* num parameters */ 3,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[1],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[561],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [90] */
- /* num parameters */ 4,
- /* num template types */ 2,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[1],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[431],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [91] */
- /* num parameters */ 3,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[1],
+ /* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[564],
/* return matcher indices */ nullptr,
@@ -9427,50 +9341,146 @@
/* const eval */ nullptr,
},
{
- /* [92] */
- /* num parameters */ 3,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[1],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[567],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [93] */
- /* num parameters */ 3,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[1],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[579],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [94] */
+ /* [84] */
/* num parameters */ 4,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[1],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[363],
- /* return matcher indices */ nullptr,
+ /* parameters */ &kParameters[343],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [95] */
+ /* [85] */
+ /* num parameters */ 5,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[0],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[165],
+ /* return matcher indices */ &kMatcherIndices[126],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [86] */
+ /* num parameters */ 5,
+ /* num template types */ 3,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[0],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[225],
+ /* return matcher indices */ &kMatcherIndices[126],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [87] */
+ /* num parameters */ 6,
+ /* num template types */ 3,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[0],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[96],
+ /* return matcher indices */ &kMatcherIndices[126],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [88] */
+ /* num parameters */ 4,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[0],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[355],
+ /* return matcher indices */ &kMatcherIndices[126],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [89] */
+ /* num parameters */ 5,
+ /* num template types */ 3,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[0],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[285],
+ /* return matcher indices */ &kMatcherIndices[126],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [90] */
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[585],
- /* return matcher indices */ nullptr,
+ /* parameters */ &kParameters[447],
+ /* return matcher indices */ &kMatcherIndices[102],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [91] */
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[431],
+ /* return matcher indices */ &kMatcherIndices[102],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [92] */
+ /* num parameters */ 4,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[2],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[419],
+ /* return matcher indices */ &kMatcherIndices[102],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [93] */
+ /* num parameters */ 5,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[2],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[265],
+ /* return matcher indices */ &kMatcherIndices[102],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [94] */
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[573],
+ /* return matcher indices */ &kMatcherIndices[102],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [95] */
+ /* num parameters */ 4,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[2],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[407],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9481,8 +9491,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
- /* return matcher indices */ &kMatcherIndices[110],
+ /* parameters */ &kParameters[1019],
+ /* return matcher indices */ &kMatcherIndices[104],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -9493,8 +9503,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[957],
- /* return matcher indices */ &kMatcherIndices[110],
+ /* parameters */ &kParameters[959],
+ /* return matcher indices */ &kMatcherIndices[104],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -9505,8 +9515,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[902],
- /* return matcher indices */ &kMatcherIndices[110],
+ /* parameters */ &kParameters[960],
+ /* return matcher indices */ &kMatcherIndices[104],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecSplat,
},
@@ -9517,8 +9527,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[492],
- /* return matcher indices */ &kMatcherIndices[110],
+ /* parameters */ &kParameters[495],
+ /* return matcher indices */ &kMatcherIndices[104],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitS,
},
@@ -9529,8 +9539,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[761],
- /* return matcher indices */ &kMatcherIndices[110],
+ /* parameters */ &kParameters[783],
+ /* return matcher indices */ &kMatcherIndices[104],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
},
@@ -9541,8 +9551,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[765],
- /* return matcher indices */ &kMatcherIndices[110],
+ /* parameters */ &kParameters[727],
+ /* return matcher indices */ &kMatcherIndices[104],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
},
@@ -9553,8 +9563,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[962],
- /* return matcher indices */ &kMatcherIndices[102],
+ /* parameters */ &kParameters[964],
+ /* return matcher indices */ &kMatcherIndices[108],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9565,8 +9575,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[963],
- /* return matcher indices */ &kMatcherIndices[106],
+ /* parameters */ &kParameters[965],
+ /* return matcher indices */ &kMatcherIndices[110],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9577,8 +9587,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[964],
- /* return matcher indices */ &kMatcherIndices[108],
+ /* parameters */ &kParameters[966],
+ /* return matcher indices */ &kMatcherIndices[114],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9589,8 +9599,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[965],
- /* return matcher indices */ &kMatcherIndices[114],
+ /* parameters */ &kParameters[967],
+ /* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9601,8 +9611,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[20],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[966],
- /* return matcher indices */ &kMatcherIndices[116],
+ /* parameters */ &kParameters[968],
+ /* return matcher indices */ &kMatcherIndices[118],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9613,7 +9623,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[817],
+ /* parameters */ &kParameters[818],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9625,7 +9635,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[816],
+ /* parameters */ &kParameters[817],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9637,7 +9647,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[815],
+ /* parameters */ &kParameters[816],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9649,7 +9659,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[814],
+ /* parameters */ &kParameters[815],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9661,7 +9671,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[813],
+ /* parameters */ &kParameters[814],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9673,7 +9683,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[812],
+ /* parameters */ &kParameters[813],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9685,7 +9695,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[811],
+ /* parameters */ &kParameters[812],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9697,7 +9707,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[810],
+ /* parameters */ &kParameters[811],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9709,7 +9719,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[809],
+ /* parameters */ &kParameters[810],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9721,7 +9731,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[808],
+ /* parameters */ &kParameters[809],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9733,7 +9743,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[763],
+ /* parameters */ &kParameters[663],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMultiply,
@@ -9745,7 +9755,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[775],
+ /* parameters */ &kParameters[667],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMultiply,
@@ -9757,7 +9767,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[777],
+ /* parameters */ &kParameters[677],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMultiply,
@@ -9769,7 +9779,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[801],
+ /* parameters */ &kParameters[679],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMultiply,
@@ -9779,9 +9789,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[797],
+ /* parameters */ &kParameters[803],
/* return matcher indices */ &kMatcherIndices[10],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMultiply,
@@ -9791,9 +9801,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[799],
+ /* parameters */ &kParameters[681],
/* return matcher indices */ &kMatcherIndices[10],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMultiply,
@@ -9803,9 +9813,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[1],
- /* parameters */ &kParameters[597],
+ /* parameters */ &kParameters[683],
/* return matcher indices */ &kMatcherIndices[69],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMultiplyMatVec,
@@ -9815,9 +9825,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[1],
- /* parameters */ &kParameters[599],
+ /* parameters */ &kParameters[685],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMultiplyVecMat,
@@ -9827,9 +9837,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 3,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[0],
- /* parameters */ &kParameters[613],
+ /* parameters */ &kParameters[691],
/* return matcher indices */ &kMatcherIndices[26],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMultiplyMatMat,
@@ -9841,7 +9851,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -9853,7 +9863,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[948],
+ /* parameters */ &kParameters[950],
/* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -9865,7 +9875,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[949],
+ /* parameters */ &kParameters[951],
/* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecSplat,
@@ -9877,7 +9887,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[753],
+ /* parameters */ &kParameters[781],
/* return matcher indices */ &kMatcherIndices[112],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitS,
@@ -9889,7 +9899,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[951],
+ /* parameters */ &kParameters[953],
/* return matcher indices */ &kMatcherIndices[132],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9901,7 +9911,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[952],
+ /* parameters */ &kParameters[954],
/* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9913,8 +9923,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[953],
- /* return matcher indices */ &kMatcherIndices[126],
+ /* parameters */ &kParameters[955],
+ /* return matcher indices */ &kMatcherIndices[128],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -9925,7 +9935,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[954],
+ /* parameters */ &kParameters[956],
/* return matcher indices */ &kMatcherIndices[124],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9937,7 +9947,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[20],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[955],
+ /* parameters */ &kParameters[957],
/* return matcher indices */ &kMatcherIndices[120],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9949,8 +9959,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[7],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[588],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[567],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9961,8 +9971,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[7],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[447],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[570],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9973,8 +9983,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[435],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[367],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9985,8 +9995,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[7],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[594],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[492],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9997,8 +10007,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[591],
- /* return matcher indices */ &kMatcherIndices[118],
+ /* parameters */ &kParameters[588],
+ /* return matcher indices */ &kMatcherIndices[126],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10009,7 +10019,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[8],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[582],
+ /* parameters */ &kParameters[585],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -10021,7 +10031,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[359],
+ /* parameters */ &kParameters[395],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -10033,7 +10043,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[5],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[570],
+ /* parameters */ &kParameters[591],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -10045,8 +10055,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[1],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[609],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[601],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10057,8 +10067,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[375],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[439],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10069,8 +10079,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[190],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[215],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10081,8 +10091,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[150],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[205],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10094,7 +10104,7 @@
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[132],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10105,8 +10115,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[383],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[371],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10117,8 +10127,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[210],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[155],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10129,8 +10139,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[391],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[383],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10141,8 +10151,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[235],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[150],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -10154,7 +10164,7 @@
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[250],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10165,8 +10175,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[72],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[78],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10177,8 +10187,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[78],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[90],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10190,7 +10200,7 @@
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[65],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10201,8 +10211,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[270],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[195],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10213,8 +10223,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[90],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[120],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10225,8 +10235,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[280],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[290],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10237,8 +10247,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[138],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[144],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10247,9 +10257,9 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10259,9 +10269,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1001],
+ /* parameters */ &kParameters[1003],
/* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10271,9 +10281,9 @@
/* num parameters */ 6,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[114],
+ /* parameters */ &kParameters[102],
/* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitS,
@@ -10283,9 +10293,9 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[453],
+ /* parameters */ &kParameters[546],
/* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitV,
@@ -10297,7 +10307,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1004],
+ /* parameters */ &kParameters[1006],
/* return matcher indices */ &kMatcherIndices[186],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10309,7 +10319,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1005],
+ /* parameters */ &kParameters[1007],
/* return matcher indices */ &kMatcherIndices[184],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10321,9 +10331,9 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[443],
+ /* parameters */ &kParameters[363],
/* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -10333,9 +10343,9 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[225],
+ /* parameters */ &kParameters[175],
/* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -10345,9 +10355,9 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[255],
+ /* parameters */ &kParameters[185],
/* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -10359,7 +10369,7 @@
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[108],
/* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -10369,9 +10379,9 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[303],
+ /* parameters */ &kParameters[379],
/* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -10381,163 +10391,163 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[245],
+ /* parameters */ &kParameters[200],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [172] */
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[299],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [172] */
- /* num parameters */ 0,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
- /* return matcher indices */ &kMatcherIndices[176],
- /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::Zero,
- },
- {
/* [173] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[995],
- /* return matcher indices */ &kMatcherIndices[176],
- /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::Identity,
- },
- {
- /* [174] */
- /* num parameters */ 8,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[57],
- /* return matcher indices */ &kMatcherIndices[176],
- /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::MatInitS,
- },
- {
- /* [175] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[795],
- /* return matcher indices */ &kMatcherIndices[176],
- /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::MatInitV,
- },
- {
- /* [176] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[14],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[998],
- /* return matcher indices */ &kMatcherIndices[180],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::Conv,
- },
- {
- /* [177] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[999],
- /* return matcher indices */ &kMatcherIndices[178],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::Conv,
- },
- {
- /* [178] */
- /* num parameters */ 4,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[403],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
- },
- {
- /* [179] */
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[260],
+ /* parameters */ &kParameters[280],
/* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [180] */
+ /* [174] */
/* num parameters */ 5,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[275],
+ /* parameters */ &kParameters[270],
/* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [181] */
+ /* [175] */
/* num parameters */ 6,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[120],
+ /* parameters */ &kParameters[114],
/* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [182] */
+ /* [176] */
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[411],
+ /* parameters */ &kParameters[315],
/* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [183] */
+ /* [177] */
/* num parameters */ 5,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[160],
+ /* parameters */ &kParameters[255],
/* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
+ /* [178] */
+ /* num parameters */ 0,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1019],
+ /* return matcher indices */ &kMatcherIndices[176],
+ /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::Zero,
+ },
+ {
+ /* [179] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[997],
+ /* return matcher indices */ &kMatcherIndices[176],
+ /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::Identity,
+ },
+ {
+ /* [180] */
+ /* num parameters */ 8,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[49],
+ /* return matcher indices */ &kMatcherIndices[176],
+ /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::MatInitS,
+ },
+ {
+ /* [181] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[801],
+ /* return matcher indices */ &kMatcherIndices[176],
+ /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::MatInitV,
+ },
+ {
+ /* [182] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1000],
+ /* return matcher indices */ &kMatcherIndices[180],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::Conv,
+ },
+ {
+ /* [183] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1001],
+ /* return matcher indices */ &kMatcherIndices[178],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::Conv,
+ },
+ {
/* [184] */
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[226],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10547,9 +10557,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[935],
+ /* parameters */ &kParameters[937],
/* return matcher indices */ &kMatcherIndices[226],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10559,7 +10569,7 @@
/* num parameters */ 16,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[0],
/* return matcher indices */ &kMatcherIndices[226],
@@ -10571,9 +10581,9 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[419],
+ /* parameters */ &kParameters[415],
/* return matcher indices */ &kMatcherIndices[226],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitV,
@@ -10585,7 +10595,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[852],
+ /* parameters */ &kParameters[840],
/* return matcher indices */ &kMatcherIndices[228],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10609,8 +10619,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[327],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[403],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10621,8 +10631,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[180],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[240],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10633,8 +10643,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[185],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[245],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10645,8 +10655,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[126],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[84],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10657,8 +10667,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[311],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[387],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10669,8 +10679,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[220],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[170],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10679,9 +10689,9 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[206],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10691,9 +10701,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[956],
+ /* parameters */ &kParameters[958],
/* return matcher indices */ &kMatcherIndices[206],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10703,9 +10713,9 @@
/* num parameters */ 12,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[16],
+ /* parameters */ &kParameters[28],
/* return matcher indices */ &kMatcherIndices[206],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitS,
@@ -10715,9 +10725,9 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[315],
+ /* parameters */ &kParameters[411],
/* return matcher indices */ &kMatcherIndices[206],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitV,
@@ -10729,7 +10739,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[941],
+ /* parameters */ &kParameters[943],
/* return matcher indices */ &kMatcherIndices[220],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10741,8 +10751,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[938],
- /* return matcher indices */ &kMatcherIndices[218],
+ /* parameters */ &kParameters[940],
+ /* return matcher indices */ &kMatcherIndices[216],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -10751,9 +10761,9 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10763,9 +10773,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[989],
+ /* parameters */ &kParameters[991],
/* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10775,9 +10785,9 @@
/* num parameters */ 6,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[84],
+ /* parameters */ &kParameters[126],
/* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitS,
@@ -10787,9 +10797,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[793],
+ /* parameters */ &kParameters[799],
/* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitV,
@@ -10801,7 +10811,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[992],
+ /* parameters */ &kParameters[994],
/* return matcher indices */ &kMatcherIndices[174],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10813,7 +10823,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[993],
+ /* parameters */ &kParameters[995],
/* return matcher indices */ &kMatcherIndices[170],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10823,9 +10833,9 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[160],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10835,9 +10845,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[983],
+ /* parameters */ &kParameters[985],
/* return matcher indices */ &kMatcherIndices[160],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10847,9 +10857,9 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[399],
+ /* parameters */ &kParameters[375],
/* return matcher indices */ &kMatcherIndices[160],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitS,
@@ -10859,7 +10869,7 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[791],
/* return matcher indices */ &kMatcherIndices[160],
@@ -10873,7 +10883,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[986],
+ /* parameters */ &kParameters[988],
/* return matcher indices */ &kMatcherIndices[166],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10885,7 +10895,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[987],
+ /* parameters */ &kParameters[989],
/* return matcher indices */ &kMatcherIndices[164],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10895,9 +10905,9 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[194],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10907,9 +10917,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1013],
+ /* parameters */ &kParameters[1015],
/* return matcher indices */ &kMatcherIndices[194],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10919,9 +10929,9 @@
/* num parameters */ 12,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[28],
+ /* parameters */ &kParameters[16],
/* return matcher indices */ &kMatcherIndices[194],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitS,
@@ -10931,9 +10941,9 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[504],
+ /* parameters */ &kParameters[576],
/* return matcher indices */ &kMatcherIndices[194],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitV,
@@ -10945,7 +10955,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1012],
+ /* parameters */ &kParameters[1014],
/* return matcher indices */ &kMatcherIndices[198],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10957,7 +10967,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1006],
+ /* parameters */ &kParameters[1008],
/* return matcher indices */ &kMatcherIndices[196],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10967,9 +10977,9 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[188],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10979,9 +10989,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1007],
+ /* parameters */ &kParameters[1009],
/* return matcher indices */ &kMatcherIndices[188],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10991,7 +11001,7 @@
/* num parameters */ 9,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[40],
/* return matcher indices */ &kMatcherIndices[188],
@@ -11003,9 +11013,9 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[450],
+ /* parameters */ &kParameters[561],
/* return matcher indices */ &kMatcherIndices[188],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitV,
@@ -11017,7 +11027,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1010],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[192],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11029,7 +11039,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1011],
+ /* parameters */ &kParameters[1013],
/* return matcher indices */ &kMatcherIndices[190],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11039,9 +11049,9 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[200],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -11051,9 +11061,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1000],
+ /* parameters */ &kParameters[1002],
/* return matcher indices */ &kMatcherIndices[200],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -11063,9 +11073,9 @@
/* num parameters */ 8,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[49],
+ /* parameters */ &kParameters[57],
/* return matcher indices */ &kMatcherIndices[200],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitS,
@@ -11075,9 +11085,9 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[439],
+ /* parameters */ &kParameters[399],
/* return matcher indices */ &kMatcherIndices[200],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitV,
@@ -11089,7 +11099,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[982],
+ /* parameters */ &kParameters[984],
/* return matcher indices */ &kMatcherIndices[204],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11101,7 +11111,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[967],
+ /* parameters */ &kParameters[969],
/* return matcher indices */ &kMatcherIndices[202],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11113,7 +11123,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[669],
+ /* parameters */ &kParameters[619],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpPlus,
@@ -11125,7 +11135,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[671],
+ /* parameters */ &kParameters[621],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpPlus,
@@ -11137,7 +11147,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[685],
+ /* parameters */ &kParameters[625],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpPlus,
@@ -11149,7 +11159,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[695],
+ /* parameters */ &kParameters[629],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpPlus,
@@ -11159,9 +11169,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[701],
+ /* parameters */ &kParameters[641],
/* return matcher indices */ &kMatcherIndices[10],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpPlus,
@@ -11173,7 +11183,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[745],
+ /* parameters */ &kParameters[645],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMinus,
@@ -11185,7 +11195,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[747],
+ /* parameters */ &kParameters[649],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMinus,
@@ -11197,7 +11207,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[755],
+ /* parameters */ &kParameters[651],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMinus,
@@ -11209,7 +11219,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[757],
+ /* parameters */ &kParameters[655],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMinus,
@@ -11219,9 +11229,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[759],
+ /* parameters */ &kParameters[659],
/* return matcher indices */ &kMatcherIndices[10],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpMinus,
@@ -11233,7 +11243,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[822],
+ /* parameters */ &kParameters[823],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11245,7 +11255,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[821],
+ /* parameters */ &kParameters[822],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11257,7 +11267,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[820],
+ /* parameters */ &kParameters[821],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11269,7 +11279,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[819],
+ /* parameters */ &kParameters[820],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11281,7 +11291,7 @@
/* num template numbers */ 2,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[3],
- /* parameters */ &kParameters[818],
+ /* parameters */ &kParameters[819],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11293,8 +11303,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[679],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[721],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpOr,
},
@@ -11305,8 +11315,8 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[681],
- /* return matcher indices */ &kMatcherIndices[36],
+ /* parameters */ &kParameters[723],
+ /* return matcher indices */ &kMatcherIndices[39],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpOr,
},
@@ -11317,7 +11327,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[36],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[683],
+ /* parameters */ &kParameters[725],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpOr,
@@ -11329,7 +11339,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[36],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[693],
+ /* parameters */ &kParameters[729],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpOr,
@@ -11339,9 +11349,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[725],
+ /* parameters */ &kParameters[757],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpShiftLeft,
@@ -11351,9 +11361,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[737],
+ /* parameters */ &kParameters[759],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpShiftLeft,
@@ -11365,7 +11375,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[35],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[739],
+ /* parameters */ &kParameters[771],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpShiftLeft,
@@ -11377,7 +11387,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[35],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[741],
+ /* parameters */ &kParameters[773],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpShiftLeft,
@@ -11389,7 +11399,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[619],
+ /* parameters */ &kParameters[693],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpDivide,
@@ -11401,7 +11411,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[625],
+ /* parameters */ &kParameters[695],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpDivide,
@@ -11413,7 +11423,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[647],
+ /* parameters */ &kParameters[697],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpDivide,
@@ -11425,7 +11435,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[651],
+ /* parameters */ &kParameters[699],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpDivide,
@@ -11435,9 +11445,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[655],
+ /* parameters */ &kParameters[701],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11447,9 +11457,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[659],
+ /* parameters */ &kParameters[703],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11459,9 +11469,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[661],
+ /* parameters */ &kParameters[705],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11471,9 +11481,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[663],
+ /* parameters */ &kParameters[707],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11485,8 +11495,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[667],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[713],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpAnd,
},
@@ -11497,8 +11507,8 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[673],
- /* return matcher indices */ &kMatcherIndices[36],
+ /* parameters */ &kParameters[715],
+ /* return matcher indices */ &kMatcherIndices[39],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpAnd,
},
@@ -11509,7 +11519,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[36],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[675],
+ /* parameters */ &kParameters[717],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpAnd,
@@ -11521,7 +11531,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[36],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[677],
+ /* parameters */ &kParameters[719],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpAnd,
@@ -11533,8 +11543,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[1019],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
@@ -11545,8 +11555,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[945],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[947],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
@@ -11557,8 +11567,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[29],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[946],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[948],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
@@ -11569,7 +11579,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[6],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -11581,7 +11591,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[942],
+ /* parameters */ &kParameters[944],
/* return matcher indices */ &kMatcherIndices[6],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -11593,7 +11603,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[30],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[943],
+ /* parameters */ &kParameters[945],
/* return matcher indices */ &kMatcherIndices[6],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11605,7 +11615,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -11617,7 +11627,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[939],
+ /* parameters */ &kParameters[941],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -11629,7 +11639,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[31],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[940],
+ /* parameters */ &kParameters[942],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11641,7 +11651,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[456],
+ /* parameters */ &kParameters[552],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::select_bool,
@@ -11653,7 +11663,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[549],
+ /* parameters */ &kParameters[555],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::select_bool,
@@ -11665,7 +11675,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[552],
+ /* parameters */ &kParameters[558],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::select_boolvec,
@@ -11677,7 +11687,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -11689,7 +11699,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[936],
+ /* parameters */ &kParameters[938],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -11701,7 +11711,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[32],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[937],
+ /* parameters */ &kParameters[939],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11713,7 +11723,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
+ /* parameters */ &kParameters[1019],
/* return matcher indices */ &kMatcherIndices[4],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -11725,7 +11735,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[933],
+ /* parameters */ &kParameters[935],
/* return matcher indices */ &kMatcherIndices[4],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -11735,9 +11745,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[34],
+ /* template types */ &kTemplateTypes[33],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[934],
+ /* parameters */ &kParameters[936],
/* return matcher indices */ &kMatcherIndices[4],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11747,7 +11757,7 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[477],
/* return matcher indices */ &kMatcherIndices[1],
@@ -11759,7 +11769,7 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[480],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11771,7 +11781,7 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[483],
/* return matcher indices */ &kMatcherIndices[30],
@@ -11785,8 +11795,8 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[869],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[871],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpNot,
},
@@ -11797,8 +11807,8 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[870],
- /* return matcher indices */ &kMatcherIndices[36],
+ /* parameters */ &kParameters[872],
+ /* return matcher indices */ &kMatcherIndices[39],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpNot,
},
@@ -11809,7 +11819,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[899],
+ /* parameters */ &kParameters[902],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -11821,7 +11831,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[898],
+ /* parameters */ &kParameters[901],
/* return matcher indices */ &kMatcherIndices[60],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -11831,9 +11841,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[901],
+ /* parameters */ &kParameters[904],
/* return matcher indices */ &kMatcherIndices[172],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11843,9 +11853,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[900],
+ /* parameters */ &kParameters[903],
/* return matcher indices */ &kMatcherIndices[78],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11857,7 +11867,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[895],
+ /* parameters */ &kParameters[898],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -11869,7 +11879,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[894],
+ /* parameters */ &kParameters[897],
/* return matcher indices */ &kMatcherIndices[60],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -11879,33 +11889,33 @@
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[423],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::insertBits,
},
{
/* [297] */
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[427],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::insertBits,
},
{
/* [298] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[893],
+ /* parameters */ &kParameters[896],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11915,9 +11925,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[892],
+ /* parameters */ &kParameters[895],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11927,9 +11937,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[607],
+ /* parameters */ &kParameters[689],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11939,9 +11949,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[629],
+ /* parameters */ &kParameters[687],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11951,9 +11961,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[891],
+ /* parameters */ &kParameters[894],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11963,9 +11973,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[890],
+ /* parameters */ &kParameters[893],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11975,9 +11985,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[889],
+ /* parameters */ &kParameters[892],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11987,9 +11997,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[888],
+ /* parameters */ &kParameters[891],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11999,9 +12009,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[887],
+ /* parameters */ &kParameters[890],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12011,9 +12021,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[886],
+ /* parameters */ &kParameters[889],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12023,9 +12033,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[773],
+ /* parameters */ &kParameters[675],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12035,9 +12045,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[771],
+ /* parameters */ &kParameters[673],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12047,9 +12057,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[769],
+ /* parameters */ &kParameters[671],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12059,9 +12069,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[767],
+ /* parameters */ &kParameters[669],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12071,9 +12081,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[904],
+ /* parameters */ &kParameters[906],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12083,9 +12093,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[903],
+ /* parameters */ &kParameters[905],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12095,9 +12105,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[885],
+ /* parameters */ &kParameters[888],
/* return matcher indices */ &kMatcherIndices[134],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12107,9 +12117,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[884],
+ /* parameters */ &kParameters[887],
/* return matcher indices */ &kMatcherIndices[96],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12119,9 +12129,9 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[519],
+ /* parameters */ &kParameters[453],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12131,9 +12141,9 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[522],
+ /* parameters */ &kParameters[450],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12141,59 +12151,59 @@
{
/* [318] */
/* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[908],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::floor,
+ },
+ {
+ /* [319] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[907],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::floor,
+ },
+ {
+ /* [320] */
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[897],
+ /* parameters */ &kParameters[900],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
- /* [319] */
+ /* [321] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[896],
+ /* parameters */ &kParameters[899],
/* return matcher indices */ &kMatcherIndices[60],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
- /* [320] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[906],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [321] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[905],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
/* [322] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[910],
+ /* parameters */ &kParameters[912],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::firstLeadingBit,
@@ -12203,9 +12213,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[909],
+ /* parameters */ &kParameters[911],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::firstLeadingBit,
@@ -12215,33 +12225,33 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[510],
+ /* parameters */ &kParameters[594],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::extractBits,
},
{
/* [325] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[513],
+ /* parameters */ &kParameters[459],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::extractBits,
},
{
/* [326] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[912],
+ /* parameters */ &kParameters[914],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12251,9 +12261,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[911],
+ /* parameters */ &kParameters[913],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12263,9 +12273,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[691],
+ /* parameters */ &kParameters[637],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12275,9 +12285,9 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[689],
+ /* parameters */ &kParameters[633],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12285,35 +12295,35 @@
{
/* [330] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[877],
- /* return matcher indices */ &kMatcherIndices[1],
+ /* parameters */ &kParameters[880],
+ /* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::quantizeToF16,
},
{
/* [331] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[876],
- /* return matcher indices */ &kMatcherIndices[30],
+ /* parameters */ &kParameters[879],
+ /* return matcher indices */ &kMatcherIndices[60],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::quantizeToF16,
},
{
/* [332] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[875],
+ /* parameters */ &kParameters[878],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12323,9 +12333,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[913],
+ /* parameters */ &kParameters[877],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12333,33 +12343,81 @@
{
/* [334] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[915],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[916],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [335] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[914],
- /* return matcher indices */ &kMatcherIndices[60],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[915],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [336] */
/* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[918],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [337] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[917],
+ /* return matcher indices */ &kMatcherIndices[60],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [338] */
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[869],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::reverseBits,
+ },
+ {
+ /* [339] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[868],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::reverseBits,
+ },
+ {
+ /* [340] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[867],
/* return matcher indices */ &kMatcherIndices[1],
@@ -12367,11 +12425,11 @@
/* const eval */ nullptr,
},
{
- /* [337] */
+ /* [341] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[866],
/* return matcher indices */ &kMatcherIndices[30],
@@ -12379,7 +12437,7 @@
/* const eval */ nullptr,
},
{
- /* [338] */
+ /* [342] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -12388,10 +12446,10 @@
/* parameters */ &kParameters[865],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::saturate,
},
{
- /* [339] */
+ /* [343] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -12400,91 +12458,43 @@
/* parameters */ &kParameters[864],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [340] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[863],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::saturate,
},
{
- /* [341] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[862],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::saturate,
- },
- {
- /* [342] */
+ /* [344] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[917],
+ /* parameters */ &kParameters[921],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
- /* [343] */
+ /* [345] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[916],
+ /* parameters */ &kParameters[920],
/* return matcher indices */ &kMatcherIndices[60],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
- /* [344] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[861],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::sign,
- },
- {
- /* [345] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[860],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::sign,
- },
- {
/* [346] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[859],
+ /* parameters */ &kParameters[863],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::sign,
},
{
/* [347] */
@@ -12493,19 +12503,19 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[858],
+ /* parameters */ &kParameters[862],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::sign,
},
{
/* [348] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[856],
+ /* parameters */ &kParameters[861],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12515,117 +12525,117 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[855],
+ /* parameters */ &kParameters[858],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [350] */
- /* num parameters */ 3,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[573],
+ /* parameters */ &kParameters[857],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [351] */
- /* num parameters */ 3,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[576],
+ /* parameters */ &kParameters[856],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [352] */
- /* num parameters */ 1,
+ /* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[854],
+ /* parameters */ &kParameters[579],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [353] */
- /* num parameters */ 1,
+ /* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[853],
+ /* parameters */ &kParameters[582],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [354] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[855],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [355] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[854],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [356] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[603],
+ /* parameters */ &kParameters[599],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::step,
},
{
- /* [355] */
+ /* [357] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[601],
+ /* parameters */ &kParameters[597],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::step,
},
{
- /* [356] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[920],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
- },
- {
- /* [357] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[918],
- /* return matcher indices */ &kMatcherIndices[60],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
- },
- {
/* [358] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[922],
+ /* parameters */ &kParameters[923],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -12637,7 +12647,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[921],
+ /* parameters */ &kParameters[1016],
/* return matcher indices */ &kMatcherIndices[60],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -12647,9 +12657,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[849],
+ /* parameters */ &kParameters[852],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12659,9 +12669,9 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[848],
+ /* parameters */ &kParameters[851],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12669,73 +12679,73 @@
{
/* [362] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[924],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[850],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [363] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[923],
- /* return matcher indices */ &kMatcherIndices[60],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[849],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [364] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[846],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[925],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [365] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[845],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[924],
+ /* return matcher indices */ &kMatcherIndices[60],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [366] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[749],
+ /* parameters */ &kParameters[847],
/* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [367] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[751],
+ /* parameters */ &kParameters[846],
/* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -12745,7 +12755,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[926],
+ /* parameters */ &kParameters[927],
/* return matcher indices */ &kMatcherIndices[62],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -12757,7 +12767,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[925],
+ /* parameters */ &kParameters[926],
/* return matcher indices */ &kMatcherIndices[60],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
@@ -12767,48 +12777,48 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[28],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[721],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[775],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpGreaterThanEqual,
+ /* const eval */ nullptr,
},
{
/* [371] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[723],
- /* return matcher indices */ &kMatcherIndices[36],
+ /* parameters */ &kParameters[779],
+ /* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpGreaterThanEqual,
+ /* const eval */ nullptr,
},
{
/* [372] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[28],
+ /* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[717],
- /* return matcher indices */ &kMatcherIndices[38],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpLessThanEqual,
+ /* parameters */ &kParameters[929],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
},
{
/* [373] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[28],
+ /* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[719],
- /* return matcher indices */ &kMatcherIndices[36],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpLessThanEqual,
+ /* parameters */ &kParameters[928],
+ /* return matcher indices */ &kMatcherIndices[60],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
},
{
/* [374] */
@@ -12817,22 +12827,22 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[713],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[753],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpGreaterThan,
+ /* const eval */ &ConstEval::OpGreaterThanEqual,
},
{
/* [375] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[28],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[715],
- /* return matcher indices */ &kMatcherIndices[36],
+ /* parameters */ &kParameters[755],
+ /* return matcher indices */ &kMatcherIndices[39],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpGreaterThan,
+ /* const eval */ &ConstEval::OpGreaterThanEqual,
},
{
/* [376] */
@@ -12841,10 +12851,10 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[711],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[749],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpLessThan,
+ /* const eval */ &ConstEval::OpLessThanEqual,
},
{
/* [377] */
@@ -12853,56 +12863,56 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[789],
- /* return matcher indices */ &kMatcherIndices[36],
+ /* parameters */ &kParameters[751],
+ /* return matcher indices */ &kMatcherIndices[39],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpLessThan,
+ /* const eval */ &ConstEval::OpLessThanEqual,
},
{
/* [378] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[735],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* parameters */ &kParameters[745],
+ /* return matcher indices */ &kMatcherIndices[41],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpGreaterThan,
},
{
/* [379] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[733],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* parameters */ &kParameters[747],
+ /* return matcher indices */ &kMatcherIndices[39],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpGreaterThan,
},
{
/* [380] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[929],
+ /* parameters */ &kParameters[769],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [381] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[928],
- /* return matcher indices */ &kMatcherIndices[30],
+ /* parameters */ &kParameters[767],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -12913,7 +12923,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1015],
+ /* parameters */ &kParameters[932],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12925,7 +12935,7 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[1009],
+ /* parameters */ &kParameters[931],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12935,63 +12945,87 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[931],
+ /* parameters */ &kParameters[1018],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countTrailingZeros,
+ /* const eval */ &ConstEval::abs,
},
{
/* [385] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[930],
+ /* parameters */ &kParameters[853],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countTrailingZeros,
+ /* const eval */ &ConstEval::abs,
},
{
/* [386] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[944],
+ /* parameters */ &kParameters[952],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countOneBits,
+ /* const eval */ &ConstEval::countTrailingZeros,
},
{
/* [387] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[932],
+ /* parameters */ &kParameters[933],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countOneBits,
+ /* const eval */ &ConstEval::countTrailingZeros,
},
{
/* [388] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[962],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::countOneBits,
+ },
+ {
+ /* [389] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[961],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::countOneBits,
+ },
+ {
+ /* [390] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[988],
+ /* parameters */ &kParameters[808],
/* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [389] */
+ /* [391] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
@@ -13003,85 +13037,61 @@
/* const eval */ nullptr,
},
{
- /* [390] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[950],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countLeadingZeros,
- },
- {
- /* [391] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[947],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countLeadingZeros,
- },
- {
/* [392] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[959],
+ /* parameters */ &kParameters[972],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::countLeadingZeros,
},
{
/* [393] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[958],
+ /* parameters */ &kParameters[963],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::countLeadingZeros,
},
{
/* [394] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[26],
+ /* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[707],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[741],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpNotEqual,
+ /* const eval */ &ConstEval::OpLessThan,
},
{
/* [395] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[26],
+ /* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[709],
- /* return matcher indices */ &kMatcherIndices[36],
+ /* parameters */ &kParameters[743],
+ /* return matcher indices */ &kMatcherIndices[39],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpNotEqual,
+ /* const eval */ &ConstEval::OpLessThan,
},
{
/* [396] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[961],
+ /* parameters */ &kParameters[974],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -13091,447 +13101,687 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[960],
+ /* parameters */ &kParameters[973],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [398] */
- /* num parameters */ 3,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[28],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[471],
+ /* parameters */ &kParameters[976],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::clamp,
+ /* const eval */ nullptr,
},
{
/* [399] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[975],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [400] */
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[28],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[540],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::clamp,
+ },
+ {
+ /* [401] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[28],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[474],
+ /* parameters */ &kParameters[537],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::clamp,
},
{
- /* [400] */
+ /* [402] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[971],
+ /* parameters */ &kParameters[978],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [401] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[970],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [402] */
- /* num parameters */ 3,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[537],
- /* return matcher indices */ &kMatcherIndices[128],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::ceil,
},
{
/* [403] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[977],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::ceil,
+ },
+ {
+ /* [404] */
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[540],
- /* return matcher indices */ &kMatcherIndices[128],
+ /* parameters */ &kParameters[510],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [404] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[973],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::atanh,
- },
- {
/* [405] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[972],
- /* return matcher indices */ &kMatcherIndices[30],
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[513],
+ /* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::atanh,
+ /* const eval */ nullptr,
},
{
/* [406] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[781],
+ /* parameters */ &kParameters[987],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::atan2,
+ /* const eval */ &ConstEval::atanh,
},
{
/* [407] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[779],
+ /* parameters */ &kParameters[986],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::atan2,
+ /* const eval */ &ConstEval::atanh,
},
{
/* [408] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[26],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[703],
- /* return matcher indices */ &kMatcherIndices[38],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpEqual,
+ /* parameters */ &kParameters[797],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::atan2,
},
{
/* [409] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[793],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::atan2,
+ },
+ {
+ /* [410] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[26],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[739],
+ /* return matcher indices */ &kMatcherIndices[41],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpNotEqual,
+ },
+ {
+ /* [411] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[705],
- /* return matcher indices */ &kMatcherIndices[36],
+ /* parameters */ &kParameters[805],
+ /* return matcher indices */ &kMatcherIndices[39],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpNotEqual,
+ },
+ {
+ /* [412] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[26],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[735],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpEqual,
},
{
- /* [410] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[975],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::atan,
- },
- {
- /* [411] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[974],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::atan,
- },
- {
- /* [412] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[977],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::asinh,
- },
- {
/* [413] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[976],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::asinh,
+ /* parameters */ &kParameters[737],
+ /* return matcher indices */ &kMatcherIndices[39],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpEqual,
},
{
/* [414] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[36],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[805],
+ /* parameters */ &kParameters[993],
/* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpXor,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::atan,
},
{
/* [415] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[36],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[665],
+ /* parameters */ &kParameters[992],
/* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpXor,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::atan,
},
{
/* [416] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[985],
+ /* parameters */ &kParameters[999],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::asin,
+ /* const eval */ &ConstEval::asinh,
},
{
/* [417] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[24],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[984],
+ /* parameters */ &kParameters[998],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::asinh,
+ },
+ {
+ /* [418] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[36],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[709],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpXor,
+ },
+ {
+ /* [419] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[36],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[711],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpXor,
+ },
+ {
+ /* [420] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1005],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::asin,
+ },
+ {
+ /* [421] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[1004],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::asin,
},
{
- /* [418] */
+ /* [422] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[991],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[922],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::any,
},
{
- /* [419] */
+ /* [423] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[990],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[1011],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::any,
},
{
- /* [420] */
+ /* [424] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[996],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::all,
},
{
- /* [421] */
+ /* [425] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[994],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[1017],
+ /* return matcher indices */ &kMatcherIndices[41],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [422] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1002],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [423] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[997],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [424] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1008],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [425] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[1003],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::all,
},
{
/* [426] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[37],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[873],
+ /* parameters */ &kParameters[949],
/* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpUnaryMinus,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
},
{
/* [427] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[37],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[874],
+ /* parameters */ &kParameters[990],
/* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpUnaryMinus,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
},
{
/* [428] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[36],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[871],
+ /* parameters */ &kParameters[934],
/* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpComplement,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::acos,
},
{
/* [429] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[36],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[872],
+ /* parameters */ &kParameters[946],
/* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpComplement,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::acos,
},
{
/* [430] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[851],
+ /* parameters */ &kParameters[875],
/* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpUnaryMinus,
},
{
/* [431] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[850],
+ /* parameters */ &kParameters[876],
/* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpUnaryMinus,
},
{
/* [432] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[36],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[908],
+ /* parameters */ &kParameters[873],
/* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::firstTrailingBit,
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpComplement,
},
{
/* [433] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[36],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[907],
+ /* parameters */ &kParameters[874],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpComplement,
+ },
+ {
+ /* [434] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[910],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::firstTrailingBit,
+ },
+ {
+ /* [435] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[909],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::firstTrailingBit,
},
{
- /* [434] */
+ /* [436] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[34],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[870],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::Identity,
+ },
+ {
+ /* [437] */
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[534],
+ /* return matcher indices */ &kMatcherIndices[208],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [438] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[615],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [439] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[613],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [440] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[611],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [441] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[623],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [442] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[609],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [443] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[607],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [444] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[605],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [445] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[603],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [446] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[731],
+ /* return matcher indices */ &kMatcherIndices[41],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [447] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[733],
+ /* return matcher indices */ &kMatcherIndices[41],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [448] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[795],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [449] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[859],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [450] */
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1019],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [451] */
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1019],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [452] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[841],
+ /* return matcher indices */ &kMatcherIndices[102],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [453] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[842],
+ /* return matcher indices */ &kMatcherIndices[102],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [454] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
@@ -13543,223 +13793,7 @@
/* const eval */ nullptr,
},
{
- /* [435] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[649],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [436] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[645],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [437] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[641],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [438] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[637],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [439] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[633],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [440] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[621],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [441] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[617],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [442] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[615],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [443] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[611],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [444] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[697],
- /* return matcher indices */ &kMatcherIndices[38],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [445] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[699],
- /* return matcher indices */ &kMatcherIndices[38],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [446] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[857],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [447] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[880],
- /* return matcher indices */ &kMatcherIndices[95],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [448] */
- /* num parameters */ 0,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [449] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[840],
- /* return matcher indices */ &kMatcherIndices[128],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [450] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[841],
- /* return matcher indices */ &kMatcherIndices[128],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [451] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[842],
- /* return matcher indices */ &kMatcherIndices[132],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [452] */
- /* num parameters */ 3,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[528],
- /* return matcher indices */ &kMatcherIndices[210],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [453] */
+ /* [455] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
@@ -13771,74 +13805,50 @@
/* const eval */ nullptr,
},
{
- /* [454] */
+ /* [456] */
/* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 2,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[5],
- /* parameters */ &kParameters[847],
- /* return matcher indices */ &kMatcherIndices[22],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [455] */
- /* num parameters */ 0,
/* num template types */ 0,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1017],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [456] */
- /* num parameters */ 3,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[525],
- /* return matcher indices */ &kMatcherIndices[30],
+ /* parameters */ &kParameters[845],
+ /* return matcher indices */ &kMatcherIndices[132],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [457] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[803],
- /* return matcher indices */ &kMatcherIndices[30],
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[5],
+ /* parameters */ &kParameters[848],
+ /* return matcher indices */ &kMatcherIndices[22],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [458] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[878],
- /* return matcher indices */ &kMatcherIndices[95],
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[531],
+ /* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [459] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[879],
- /* return matcher indices */ &kMatcherIndices[95],
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[617],
+ /* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -13869,35 +13879,35 @@
{
/* [462] */
/* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[883],
- /* return matcher indices */ &kMatcherIndices[30],
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[884],
+ /* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [463] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[38],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[743],
- /* return matcher indices */ &kMatcherIndices[110],
+ /* parameters */ &kParameters[885],
+ /* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [464] */
- /* num parameters */ 3,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[516],
+ /* parameters */ &kParameters[886],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -13905,60 +13915,60 @@
{
/* [465] */
/* num parameters */ 2,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[727],
- /* return matcher indices */ &kMatcherIndices[95],
+ /* parameters */ &kParameters[777],
+ /* return matcher indices */ &kMatcherIndices[104],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [466] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[729],
- /* return matcher indices */ &kMatcherIndices[4],
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[456],
+ /* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [467] */
/* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[22],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[731],
- /* return matcher indices */ &kMatcherIndices[1],
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[761],
+ /* return matcher indices */ &kMatcherIndices[95],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [468] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[927],
- /* return matcher indices */ &kMatcherIndices[1],
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[763],
+ /* return matcher indices */ &kMatcherIndices[4],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [469] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[33],
- /* template numbers */ &kTemplateNumbers[8],
- /* parameters */ &kParameters[1014],
- /* return matcher indices */ &kMatcherIndices[95],
+ /* template types */ &kTemplateTypes[25],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[765],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -13966,234 +13976,258 @@
/* [470] */
/* num parameters */ 1,
/* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[33],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[868],
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[930],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::Identity,
+ /* const eval */ nullptr,
+ },
+ {
+ /* [471] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[34],
+ /* template numbers */ &kTemplateNumbers[8],
+ /* parameters */ &kParameters[1010],
+ /* return matcher indices */ &kMatcherIndices[95],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [472] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[38],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[883],
+ /* return matcher indices */ &kMatcherIndices[95],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
},
};
constexpr IntrinsicInfo kBuiltins[] = {
{
/* [0] */
- /* fn abs<T : fiu32_f16>(T) -> T */
- /* fn abs<N : num, T : fiu32_f16>(vec<N, T>) -> vec<N, T> */
+ /* fn abs<T : fia_fiu32_f16>(T) -> T */
+ /* fn abs<N : num, T : fia_fiu32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[382],
+ /* overloads */ &kOverloads[384],
},
{
/* [1] */
- /* fn acos<T : f32_f16>(T) -> T */
- /* fn acos<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* fn acos<T : fa_f32_f16>(@test_value(0.87758256189) T) -> T */
+ /* fn acos<N : num, T : fa_f32_f16>(@test_value(0.87758256189) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[424],
+ /* overloads */ &kOverloads[428],
},
{
/* [2] */
/* fn acosh<T : f32_f16>(T) -> T */
/* fn acosh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[422],
+ /* overloads */ &kOverloads[426],
},
{
/* [3] */
/* fn all(bool) -> bool */
/* fn all<N : num>(vec<N, bool>) -> bool */
/* num overloads */ 2,
- /* overloads */ &kOverloads[420],
+ /* overloads */ &kOverloads[424],
},
{
/* [4] */
/* fn any(bool) -> bool */
/* fn any<N : num>(vec<N, bool>) -> bool */
/* num overloads */ 2,
- /* overloads */ &kOverloads[418],
+ /* overloads */ &kOverloads[422],
},
{
/* [5] */
/* fn arrayLength<T, A : access>(ptr<storage, array<T>, A>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[469],
+ /* overloads */ &kOverloads[471],
},
{
/* [6] */
/* fn asin<T : fa_f32_f16>(@test_value(0.479425538604) T) -> T */
/* fn asin<N : num, T : fa_f32_f16>(@test_value(0.479425538604) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[416],
+ /* overloads */ &kOverloads[420],
},
{
/* [7] */
/* fn asinh<T : fa_f32_f16>(T) -> T */
/* fn asinh<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[412],
+ /* overloads */ &kOverloads[416],
},
{
/* [8] */
/* fn atan<T : fa_f32_f16>(T) -> T */
/* fn atan<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[410],
+ /* overloads */ &kOverloads[414],
},
{
/* [9] */
/* fn atan2<T : fa_f32_f16>(T, T) -> T */
/* fn atan2<T : fa_f32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[406],
+ /* overloads */ &kOverloads[408],
},
{
/* [10] */
/* fn atanh<T : fa_f32_f16>(@test_value(0.5) T) -> T */
/* fn atanh<N : num, T : fa_f32_f16>(@test_value(0.5) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[404],
+ /* overloads */ &kOverloads[406],
},
{
/* [11] */
- /* fn ceil<T : f32_f16>(T) -> T */
- /* fn ceil<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* fn ceil<T : fa_f32_f16>(@test_value(1.5) T) -> T */
+ /* fn ceil<N : num, T : fa_f32_f16>(@test_value(1.5) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[400],
+ /* overloads */ &kOverloads[402],
},
{
/* [12] */
/* fn clamp<T : fia_fiu32_f16>(T, T, T) -> T */
/* fn clamp<T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[398],
+ /* overloads */ &kOverloads[400],
},
{
/* [13] */
/* fn cos<T : f32_f16>(T) -> T */
/* fn cos<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[396],
+ /* overloads */ &kOverloads[398],
},
{
/* [14] */
/* fn cosh<T : f32_f16>(T) -> T */
/* fn cosh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[392],
+ /* overloads */ &kOverloads[396],
},
{
/* [15] */
/* fn countLeadingZeros<T : iu32>(T) -> T */
/* fn countLeadingZeros<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[390],
+ /* overloads */ &kOverloads[392],
},
{
/* [16] */
/* fn countOneBits<T : iu32>(T) -> T */
/* fn countOneBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[386],
+ /* overloads */ &kOverloads[388],
},
{
/* [17] */
/* fn countTrailingZeros<T : iu32>(T) -> T */
/* fn countTrailingZeros<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[384],
+ /* overloads */ &kOverloads[386],
},
{
/* [18] */
/* fn cross<T : f32_f16>(vec3<T>, vec3<T>) -> vec3<T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[463],
+ /* overloads */ &kOverloads[465],
},
{
/* [19] */
/* fn degrees<T : f32_f16>(T) -> T */
/* fn degrees<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[380],
+ /* overloads */ &kOverloads[382],
},
{
/* [20] */
/* fn determinant<N : num, T : f32_f16>(mat<N, N, T>) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[468],
+ /* overloads */ &kOverloads[470],
},
{
/* [21] */
/* fn distance<T : f32_f16>(T, T) -> T */
/* fn distance<N : num, T : f32_f16>(vec<N, T>, vec<N, T>) -> T */
/* num overloads */ 2,
- /* overloads */ &kOverloads[378],
+ /* overloads */ &kOverloads[380],
},
{
/* [22] */
/* fn dot<N : num, T : fiu32_f16>(vec<N, T>, vec<N, T>) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[467],
+ /* overloads */ &kOverloads[469],
},
{
/* [23] */
/* fn dot4I8Packed(u32, u32) -> i32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[466],
+ /* overloads */ &kOverloads[468],
},
{
/* [24] */
/* fn dot4U8Packed(u32, u32) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[465],
+ /* overloads */ &kOverloads[467],
},
{
/* [25] */
/* fn dpdx(f32) -> f32 */
/* fn dpdx<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[368],
+ /* overloads */ &kOverloads[372],
},
{
/* [26] */
/* fn dpdxCoarse(f32) -> f32 */
/* fn dpdxCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[362],
+ /* overloads */ &kOverloads[368],
},
{
/* [27] */
/* fn dpdxFine(f32) -> f32 */
/* fn dpdxFine<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[358],
+ /* overloads */ &kOverloads[364],
},
{
/* [28] */
/* fn dpdy(f32) -> f32 */
/* fn dpdy<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[356],
+ /* overloads */ &kOverloads[358],
},
{
/* [29] */
/* fn dpdyCoarse(f32) -> f32 */
/* fn dpdyCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[342],
+ /* overloads */ &kOverloads[344],
},
{
/* [30] */
/* fn dpdyFine(f32) -> f32 */
/* fn dpdyFine<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[334],
+ /* overloads */ &kOverloads[336],
},
{
/* [31] */
/* fn exp<T : f32_f16>(T) -> T */
/* fn exp<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[332],
+ /* overloads */ &kOverloads[334],
},
{
/* [32] */
@@ -14213,7 +14247,7 @@
/* [34] */
/* fn faceForward<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[464],
+ /* overloads */ &kOverloads[466],
},
{
/* [35] */
@@ -14227,14 +14261,14 @@
/* fn firstTrailingBit<T : iu32>(T) -> T */
/* fn firstTrailingBit<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[432],
+ /* overloads */ &kOverloads[434],
},
{
/* [37] */
- /* fn floor<T : f32_f16>(T) -> T */
- /* fn floor<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* fn floor<T : fa_f32_f16>(@test_value(1.5) T) -> T */
+ /* fn floor<N : num, T : fa_f32_f16>(@test_value(1.5) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[320],
+ /* overloads */ &kOverloads[318],
},
{
/* [38] */
@@ -14269,7 +14303,7 @@
/* fn fwidthCoarse(f32) -> f32 */
/* fn fwidthCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[318],
+ /* overloads */ &kOverloads[320],
},
{
/* [43] */
@@ -14353,37 +14387,37 @@
/* [54] */
/* fn normalize<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[462],
+ /* overloads */ &kOverloads[464],
},
{
/* [55] */
/* fn pack2x16float(vec2<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[461],
+ /* overloads */ &kOverloads[463],
},
{
/* [56] */
/* fn pack2x16snorm(vec2<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[460],
+ /* overloads */ &kOverloads[462],
},
{
/* [57] */
/* fn pack2x16unorm(vec2<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[447],
+ /* overloads */ &kOverloads[472],
},
{
/* [58] */
/* fn pack4x8snorm(vec4<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[459],
+ /* overloads */ &kOverloads[461],
},
{
/* [59] */
/* fn pack4x8unorm(vec4<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[458],
+ /* overloads */ &kOverloads[460],
},
{
/* [60] */
@@ -14394,46 +14428,53 @@
},
{
/* [61] */
- /* fn radians<T : f32_f16>(T) -> T */
- /* fn radians<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* fn quantizeToF16(f32) -> f32 */
+ /* fn quantizeToF16<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
/* overloads */ &kOverloads[330],
},
{
/* [62] */
- /* fn reflect<N : num, T : f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[457],
+ /* fn radians<T : f32_f16>(T) -> T */
+ /* fn radians<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[332],
},
{
/* [63] */
- /* fn refract<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T> */
+ /* fn reflect<N : num, T : f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[456],
+ /* overloads */ &kOverloads[459],
},
{
/* [64] */
- /* fn reverseBits<T : iu32>(T) -> T */
- /* fn reverseBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[336],
+ /* fn refract<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T> */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[458],
},
{
/* [65] */
- /* fn round<T : f32_f16>(T) -> T */
- /* fn round<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* fn reverseBits<T : iu32>(T) -> T */
+ /* fn reverseBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
/* overloads */ &kOverloads[338],
},
{
/* [66] */
- /* fn saturate<T : fa_f32_f16>(@test_value(2) T) -> T */
- /* fn saturate<T : fa_f32_f16, N : num>(@test_value(2) vec<N, T>) -> vec<N, T> */
+ /* fn round<T : f32_f16>(T) -> T */
+ /* fn round<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
/* overloads */ &kOverloads[340],
},
{
/* [67] */
+ /* fn saturate<T : fa_f32_f16>(@test_value(2) T) -> T */
+ /* fn saturate<T : fa_f32_f16, N : num>(@test_value(2) vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[342],
+ },
+ {
+ /* [68] */
/* fn select<T : scalar>(T, T, bool) -> T */
/* fn select<T : scalar, N : num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T> */
/* fn select<N : num, T : scalar>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T> */
@@ -14441,118 +14482,118 @@
/* overloads */ &kOverloads[276],
},
{
- /* [68] */
+ /* [69] */
/* fn sign<T : fa_f32_f16>(T) -> T */
/* fn sign<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[344],
- },
- {
- /* [69] */
- /* fn sin<T : f32_f16>(T) -> T */
- /* fn sin<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
/* overloads */ &kOverloads[346],
},
{
/* [70] */
- /* fn sinh<T : f32_f16>(T) -> T */
- /* fn sinh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* fn sin<T : f32_f16>(T) -> T */
+ /* fn sin<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
/* overloads */ &kOverloads[348],
},
{
/* [71] */
- /* fn smoothstep<T : f32_f16>(T, T, T) -> T */
- /* fn smoothstep<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
+ /* fn sinh<T : f32_f16>(T) -> T */
+ /* fn sinh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
/* overloads */ &kOverloads[350],
},
{
/* [72] */
- /* fn sqrt<T : f32_f16>(T) -> T */
- /* fn sqrt<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* fn smoothstep<T : f32_f16>(T, T, T) -> T */
+ /* fn smoothstep<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
/* overloads */ &kOverloads[352],
},
{
/* [73] */
- /* fn step<T : fa_f32_f16>(T, T) -> T */
- /* fn step<N : num, T : fa_f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
+ /* fn sqrt<T : f32_f16>(T) -> T */
+ /* fn sqrt<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
/* overloads */ &kOverloads[354],
},
{
/* [74] */
- /* fn storageBarrier() */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[455],
+ /* fn step<T : fa_f32_f16>(T, T) -> T */
+ /* fn step<N : num, T : fa_f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[356],
},
{
/* [75] */
- /* fn tan<T : f32_f16>(T) -> T */
- /* fn tan<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[430],
+ /* fn storageBarrier() */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[450],
},
{
/* [76] */
- /* fn tanh<T : f32_f16>(T) -> T */
- /* fn tanh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* fn tan<T : f32_f16>(T) -> T */
+ /* fn tan<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
/* overloads */ &kOverloads[360],
},
{
/* [77] */
+ /* fn tanh<T : f32_f16>(T) -> T */
+ /* fn tanh<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[362],
+ },
+ {
+ /* [78] */
/* fn transpose<M : num, N : num, T : f32_f16>(mat<M, N, T>) -> mat<N, M, T> */
/* num overloads */ 1,
+ /* overloads */ &kOverloads[457],
+ },
+ {
+ /* [79] */
+ /* fn trunc<T : f32_f16>(T) -> T */
+ /* fn trunc<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[366],
+ },
+ {
+ /* [80] */
+ /* fn unpack2x16float(u32) -> vec2<f32> */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[456],
+ },
+ {
+ /* [81] */
+ /* fn unpack2x16snorm(u32) -> vec2<f32> */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[455],
+ },
+ {
+ /* [82] */
+ /* fn unpack2x16unorm(u32) -> vec2<f32> */
+ /* num overloads */ 1,
/* overloads */ &kOverloads[454],
},
{
- /* [78] */
- /* fn trunc<T : f32_f16>(T) -> T */
- /* fn trunc<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[364],
- },
- {
- /* [79] */
- /* fn unpack2x16float(u32) -> vec2<f32> */
+ /* [83] */
+ /* fn unpack4x8snorm(u32) -> vec4<f32> */
/* num overloads */ 1,
/* overloads */ &kOverloads[453],
},
{
- /* [80] */
- /* fn unpack2x16snorm(u32) -> vec2<f32> */
+ /* [84] */
+ /* fn unpack4x8unorm(u32) -> vec4<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[434],
+ /* overloads */ &kOverloads[452],
},
{
- /* [81] */
- /* fn unpack2x16unorm(u32) -> vec2<f32> */
+ /* [85] */
+ /* fn workgroupBarrier() */
/* num overloads */ 1,
/* overloads */ &kOverloads[451],
},
{
- /* [82] */
- /* fn unpack4x8snorm(u32) -> vec4<f32> */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[450],
- },
- {
- /* [83] */
- /* fn unpack4x8unorm(u32) -> vec4<f32> */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[449],
- },
- {
- /* [84] */
- /* fn workgroupBarrier() */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[448],
- },
- {
- /* [85] */
+ /* [86] */
/* fn textureDimensions<T : fiu32>(texture: texture_1d<T>) -> u32 */
/* fn textureDimensions<T : fiu32, L : iu32>(texture: texture_1d<T>, level: L) -> u32 */
/* fn textureDimensions<T : fiu32>(texture: texture_2d<T>) -> vec2<u32> */
@@ -14584,7 +14625,7 @@
/* overloads */ &kOverloads[0],
},
{
- /* [86] */
+ /* [87] */
/* fn textureGather<T : fiu32, C : iu32>(@const component: C, texture: texture_2d<T>, sampler: sampler, coords: vec2<f32>) -> vec4<T> */
/* fn textureGather<T : fiu32, C : iu32>(@const component: C, texture: texture_2d<T>, sampler: sampler, coords: vec2<f32>, @const offset: vec2<i32>) -> vec4<T> */
/* fn textureGather<T : fiu32, C : iu32, A : iu32>(@const component: C, texture: texture_2d_array<T>, sampler: sampler, coords: vec2<f32>, array_index: A) -> vec4<T> */
@@ -14598,10 +14639,10 @@
/* fn textureGather(texture: texture_depth_cube, sampler: sampler, coords: vec3<f32>) -> vec4<f32> */
/* fn textureGather<A : iu32>(texture: texture_depth_cube_array, sampler: sampler, coords: vec3<f32>, array_index: A) -> vec4<f32> */
/* num overloads */ 12,
- /* overloads */ &kOverloads[72],
+ /* overloads */ &kOverloads[84],
},
{
- /* [87] */
+ /* [88] */
/* fn textureGatherCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32) -> vec4<f32> */
/* fn textureGatherCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32, @const offset: vec2<i32>) -> vec4<f32> */
/* fn textureGatherCompare<A : iu32>(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: A, depth_ref: f32) -> vec4<f32> */
@@ -14612,7 +14653,7 @@
/* overloads */ &kOverloads[190],
},
{
- /* [88] */
+ /* [89] */
/* fn textureNumLayers<T : fiu32>(texture: texture_2d_array<T>) -> u32 */
/* fn textureNumLayers<T : fiu32>(texture: texture_cube_array<T>) -> u32 */
/* fn textureNumLayers(texture: texture_depth_2d_array) -> u32 */
@@ -14622,7 +14663,7 @@
/* overloads */ &kOverloads[242],
},
{
- /* [89] */
+ /* [90] */
/* fn textureNumLevels<T : fiu32>(texture: texture_1d<T>) -> u32 */
/* fn textureNumLevels<T : fiu32>(texture: texture_2d<T>) -> u32 */
/* fn textureNumLevels<T : fiu32>(texture: texture_2d_array<T>) -> u32 */
@@ -14637,14 +14678,14 @@
/* overloads */ &kOverloads[107],
},
{
- /* [90] */
+ /* [91] */
/* fn textureNumSamples<T : fiu32>(texture: texture_multisampled_2d<T>) -> u32 */
/* fn textureNumSamples(texture: texture_depth_multisampled_2d) -> u32 */
/* num overloads */ 2,
- /* overloads */ &kOverloads[388],
+ /* overloads */ &kOverloads[390],
},
{
- /* [91] */
+ /* [92] */
/* fn textureSample(texture: texture_1d<f32>, sampler: sampler, coords: f32) -> vec4<f32> */
/* fn textureSample(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>) -> vec4<f32> */
/* fn textureSample(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, @const offset: vec2<i32>) -> vec4<f32> */
@@ -14664,7 +14705,7 @@
/* overloads */ &kOverloads[57],
},
{
- /* [92] */
+ /* [93] */
/* fn textureSampleBias(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, bias: f32) -> vec4<f32> */
/* fn textureSampleBias(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, bias: f32, @const offset: vec2<i32>) -> vec4<f32> */
/* fn textureSampleBias<A : iu32>(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: A, bias: f32) -> vec4<f32> */
@@ -14677,7 +14718,7 @@
/* overloads */ &kOverloads[144],
},
{
- /* [93] */
+ /* [94] */
/* fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32) -> f32 */
/* fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32, @const offset: vec2<i32>) -> f32 */
/* fn textureSampleCompare<A : iu32>(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: A, depth_ref: f32) -> f32 */
@@ -14685,10 +14726,10 @@
/* fn textureSampleCompare(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3<f32>, depth_ref: f32) -> f32 */
/* fn textureSampleCompare<A : iu32>(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3<f32>, array_index: A, depth_ref: f32) -> f32 */
/* num overloads */ 6,
- /* overloads */ &kOverloads[178],
+ /* overloads */ &kOverloads[166],
},
{
- /* [94] */
+ /* [95] */
/* fn textureSampleCompareLevel(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32) -> f32 */
/* fn textureSampleCompareLevel(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2<f32>, depth_ref: f32, @const offset: vec2<i32>) -> f32 */
/* fn textureSampleCompareLevel<A : iu32>(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: A, depth_ref: f32) -> f32 */
@@ -14696,10 +14737,10 @@
/* fn textureSampleCompareLevel(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3<f32>, depth_ref: f32) -> f32 */
/* fn textureSampleCompareLevel<A : iu32>(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3<f32>, array_index: A, depth_ref: f32) -> f32 */
/* num overloads */ 6,
- /* overloads */ &kOverloads[166],
+ /* overloads */ &kOverloads[172],
},
{
- /* [95] */
+ /* [96] */
/* fn textureSampleGrad(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, ddx: vec2<f32>, ddy: vec2<f32>) -> vec4<f32> */
/* fn textureSampleGrad(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, ddx: vec2<f32>, ddy: vec2<f32>, @const offset: vec2<i32>) -> vec4<f32> */
/* fn textureSampleGrad<A : iu32>(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: A, ddx: vec2<f32>, ddy: vec2<f32>) -> vec4<f32> */
@@ -14712,7 +14753,7 @@
/* overloads */ &kOverloads[152],
},
{
- /* [96] */
+ /* [97] */
/* fn textureSampleLevel(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, level: f32) -> vec4<f32> */
/* fn textureSampleLevel(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>, level: f32, @const offset: vec2<i32>) -> vec4<f32> */
/* fn textureSampleLevel<A : iu32>(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: A, level: f32) -> vec4<f32> */
@@ -14732,14 +14773,14 @@
/* overloads */ &kOverloads[27],
},
{
- /* [97] */
+ /* [98] */
/* fn textureSampleBaseClampToEdge(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>) -> vec4<f32> */
/* fn textureSampleBaseClampToEdge(texture: texture_external, sampler: sampler, coords: vec2<f32>) -> vec4<f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[402],
+ /* overloads */ &kOverloads[404],
},
{
- /* [98] */
+ /* [99] */
/* fn textureStore<C : iu32>(texture: texture_storage_1d<f32_texel_format, write>, coords: C, value: vec4<f32>) */
/* fn textureStore<C : iu32>(texture: texture_storage_2d<f32_texel_format, write>, coords: vec2<C>, value: vec4<f32>) */
/* fn textureStore<C : iu32, A : iu32>(texture: texture_storage_2d_array<f32_texel_format, write>, coords: vec2<C>, array_index: A, value: vec4<f32>) */
@@ -14753,10 +14794,10 @@
/* fn textureStore<C : iu32, A : iu32>(texture: texture_storage_2d_array<u32_texel_format, write>, coords: vec2<C>, array_index: A, value: vec4<u32>) */
/* fn textureStore(texture: texture_storage_3d<u32_texel_format, write>, coords: vec3<i32>, value: vec4<u32>) */
/* num overloads */ 12,
- /* overloads */ &kOverloads[84],
+ /* overloads */ &kOverloads[72],
},
{
- /* [99] */
+ /* [100] */
/* fn textureLoad<T : fiu32, C : iu32, L : iu32>(texture: texture_1d<T>, coords: C, level: L) -> vec4<T> */
/* fn textureLoad<T : fiu32, C : iu32, L : iu32>(texture: texture_2d<T>, coords: vec2<C>, level: L) -> vec4<T> */
/* fn textureLoad<T : fiu32, C : iu32, A : iu32, L : iu32>(texture: texture_2d_array<T>, coords: vec2<C>, array_index: A, level: L) -> vec4<T> */
@@ -14770,76 +14811,76 @@
/* overloads */ &kOverloads[135],
},
{
- /* [100] */
+ /* [101] */
/* fn atomicLoad<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[446],
+ /* overloads */ &kOverloads[449],
},
{
- /* [101] */
+ /* [102] */
/* fn atomicStore<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) */
/* num overloads */ 1,
+ /* overloads */ &kOverloads[448],
+ },
+ {
+ /* [103] */
+ /* fn atomicAdd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[445],
+ },
+ {
+ /* [104] */
+ /* fn atomicSub<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[444],
+ },
+ {
+ /* [105] */
+ /* fn atomicMax<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* num overloads */ 1,
/* overloads */ &kOverloads[443],
},
{
- /* [102] */
- /* fn atomicAdd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* [106] */
+ /* fn atomicMin<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
/* overloads */ &kOverloads[442],
},
{
- /* [103] */
- /* fn atomicSub<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* [107] */
+ /* fn atomicAnd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
/* overloads */ &kOverloads[441],
},
{
- /* [104] */
- /* fn atomicMax<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* [108] */
+ /* fn atomicOr<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
/* overloads */ &kOverloads[440],
},
{
- /* [105] */
- /* fn atomicMin<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* [109] */
+ /* fn atomicXor<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
/* overloads */ &kOverloads[439],
},
{
- /* [106] */
- /* fn atomicAnd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* [110] */
+ /* fn atomicExchange<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
/* overloads */ &kOverloads[438],
},
{
- /* [107] */
- /* fn atomicOr<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* [111] */
+ /* fn atomicCompareExchangeWeak<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> __atomic_compare_exchange_result<T> */
/* num overloads */ 1,
/* overloads */ &kOverloads[437],
},
{
- /* [108] */
- /* fn atomicXor<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[436],
- },
- {
- /* [109] */
- /* fn atomicExchange<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[435],
- },
- {
- /* [110] */
- /* fn atomicCompareExchangeWeak<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> __atomic_compare_exchange_result<T> */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[452],
- },
- {
- /* [111] */
+ /* [112] */
/* fn _tint_materialize<T>(T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[470],
+ /* overloads */ &kOverloads[436],
},
};
@@ -14856,14 +14897,14 @@
/* op ~<T : ia_iu32>(T) -> T */
/* op ~<T : ia_iu32, N : num>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[428],
+ /* overloads */ &kOverloads[432],
},
{
/* [2] */
/* op -<T : fia_fi32_f16>(T) -> T */
/* op -<T : fia_fi32_f16, N : num>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[426],
+ /* overloads */ &kOverloads[430],
},
};
constexpr uint8_t kUnaryOperatorNot = 0;
@@ -14928,7 +14969,7 @@
/* op ^<T : ia_iu32>(T, T) -> T */
/* op ^<T : ia_iu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[414],
+ /* overloads */ &kOverloads[418],
},
{
/* [6] */
@@ -14952,55 +14993,55 @@
/* [8] */
/* op &&(bool, bool) -> bool */
/* num overloads */ 1,
- /* overloads */ &kOverloads[444],
+ /* overloads */ &kOverloads[446],
},
{
/* [9] */
/* op ||(bool, bool) -> bool */
/* num overloads */ 1,
- /* overloads */ &kOverloads[445],
+ /* overloads */ &kOverloads[447],
},
{
/* [10] */
/* op ==<T : scalar>(T, T) -> bool */
/* op ==<T : scalar, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[408],
+ /* overloads */ &kOverloads[412],
},
{
/* [11] */
/* op !=<T : scalar>(T, T) -> bool */
/* op !=<T : scalar, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[394],
+ /* overloads */ &kOverloads[410],
},
{
/* [12] */
/* op <<T : fia_fiu32_f16>(T, T) -> bool */
/* op <<T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[376],
+ /* overloads */ &kOverloads[394],
},
{
/* [13] */
/* op ><T : fia_fiu32_f16>(T, T) -> bool */
/* op ><T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[374],
+ /* overloads */ &kOverloads[378],
},
{
/* [14] */
/* op <=<T : fia_fiu32_f16>(T, T) -> bool */
/* op <=<T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[372],
+ /* overloads */ &kOverloads[376],
},
{
/* [15] */
/* op >=<T : fia_fiu32_f16>(T, T) -> bool */
/* op >=<T : fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[370],
+ /* overloads */ &kOverloads[374],
},
{
/* [16] */
@@ -15016,7 +15057,7 @@
/* op >><T : iu32>(T, u32) -> T */
/* op >><T : iu32, N : num>(vec<N, T>, vec<N, u32>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[366],
+ /* overloads */ &kOverloads[370],
},
};
constexpr uint8_t kBinaryOperatorPlus = 0;
@@ -15160,7 +15201,7 @@
/* conv mat2x4<T : f16>(mat2x4<f32>) -> mat2x4<f16> */
/* conv mat2x4<T : f32>(mat2x4<f16>) -> mat2x4<f32> */
/* num overloads */ 6,
- /* overloads */ &kOverloads[172],
+ /* overloads */ &kOverloads[178],
},
{
/* [11] */
diff --git a/src/tint/resolver/override_test.cc b/src/tint/resolver/override_test.cc
index 4fdbcee..a12d3c1 100644
--- a/src/tint/resolver/override_test.cc
+++ b/src/tint/resolver/override_test.cc
@@ -91,7 +91,7 @@
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(56:78 error: override IDs must be unique
+ EXPECT_EQ(r()->error(), R"(56:78 error: @id values must be unique
12:34 note: a override with an ID of 7 was previously declared here:)");
}
@@ -100,7 +100,7 @@
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: override IDs must be between 0 and 65535");
+ EXPECT_EQ(r()->error(), "12:34 error: @id value must be between 0 and 65535");
}
TEST_F(ResolverOverrideTest, F16_TemporallyBan) {
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 3252829..cb24955 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -461,18 +461,18 @@
return nullptr;
}
if (!materialized->Type()->IsAnyOf<sem::I32, sem::U32>()) {
- AddError("'id' must be an i32 or u32 value", id_attr->source);
+ AddError("@id must be an i32 or u32 value", id_attr->source);
return nullptr;
}
auto const_value = materialized->ConstantValue();
auto value = const_value->As<AInt>();
if (value < 0) {
- AddError("'id' value must be non-negative", id_attr->source);
+ AddError("@id value must be non-negative", id_attr->source);
return nullptr;
}
if (value > std::numeric_limits<decltype(OverrideId::value)>::max()) {
- AddError("override IDs must be between 0 and " +
+ AddError("@id value must be between 0 and " +
std::to_string(std::numeric_limits<decltype(OverrideId::value)>::max()),
id_attr->source);
return nullptr;
@@ -638,14 +638,14 @@
return nullptr;
}
if (!materialized->Type()->IsAnyOf<sem::I32, sem::U32>()) {
- AddError("'binding' must be an i32 or u32 value", attr->source);
+ AddError("@binding must be an i32 or u32 value", attr->source);
return nullptr;
}
auto const_value = materialized->ConstantValue();
auto value = const_value->As<AInt>();
if (value < 0) {
- AddError("'binding' value must be non-negative", attr->source);
+ AddError("@binding value must be non-negative", attr->source);
return nullptr;
}
binding = u32(value);
@@ -662,14 +662,14 @@
return nullptr;
}
if (!materialized->Type()->IsAnyOf<sem::I32, sem::U32>()) {
- AddError("'group' must be an i32 or u32 value", attr->source);
+ AddError("@group must be an i32 or u32 value", attr->source);
return nullptr;
}
auto const_value = materialized->ConstantValue();
auto value = const_value->As<AInt>();
if (value < 0) {
- AddError("'group' value must be non-negative", attr->source);
+ AddError("@group value must be non-negative", attr->source);
return nullptr;
}
group = u32(value);
@@ -679,22 +679,11 @@
std::optional<uint32_t> location;
if (auto* attr = ast::GetAttribute<ast::LocationAttribute>(var->attributes)) {
- auto* materialized = Materialize(Expression(attr->expr));
- if (!materialized) {
+ auto value = LocationAttribute(attr);
+ if (!value) {
return nullptr;
}
- if (!materialized->Type()->IsAnyOf<sem::I32, sem::U32>()) {
- AddError("'location' must be an i32 or u32 value", attr->source);
- return nullptr;
- }
-
- auto const_value = materialized->ConstantValue();
- auto value = const_value->As<AInt>();
- if (value < 0) {
- AddError("'location' value must be non-negative", attr->source);
- return nullptr;
- }
- location = u32(value);
+ location = value.Get();
}
sem = builder_->create<sem::GlobalVariable>(
@@ -748,48 +737,36 @@
sem::BindingPoint binding_point;
if (param->HasBindingPoint()) {
{
+ ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "@binding value"};
+ TINT_SCOPED_ASSIGNMENT(expr_eval_stage_constraint_, constraint);
+
auto* attr = ast::GetAttribute<ast::BindingAttribute>(param->attributes);
- auto* materialize = Materialize(Expression(attr->expr));
- if (!materialize) {
+ auto* materialized = Materialize(Expression(attr->expr));
+ if (!materialized) {
return nullptr;
}
- auto* c = materialize->ConstantValue();
- if (!c) {
- // TODO(crbug.com/tint/1633): Add error message about invalid materialization when
- // binding can be an expression.
- return nullptr;
- }
- binding_point.binding = c->As<uint32_t>();
+ binding_point.binding = materialized->ConstantValue()->As<uint32_t>();
}
{
+ ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "@group value"};
+ TINT_SCOPED_ASSIGNMENT(expr_eval_stage_constraint_, constraint);
+
auto* attr = ast::GetAttribute<ast::GroupAttribute>(param->attributes);
- auto* materialize = Materialize(Expression(attr->expr));
- if (!materialize) {
+ auto* materialized = Materialize(Expression(attr->expr));
+ if (!materialized) {
return nullptr;
}
- auto* c = materialize->ConstantValue();
- if (!c) {
- // TODO(crbug.com/tint/1633): Add error message about invalid materialization when
- // binding can be an expression.
- return nullptr;
- }
- binding_point.group = c->As<uint32_t>();
+ binding_point.group = materialized->ConstantValue()->As<uint32_t>();
}
}
std::optional<uint32_t> location;
- if (auto* l = ast::GetAttribute<ast::LocationAttribute>(param->attributes)) {
- auto* materialize = Materialize(Expression(l->expr));
- if (!materialize) {
+ if (auto* attr = ast::GetAttribute<ast::LocationAttribute>(param->attributes)) {
+ auto value = LocationAttribute(attr);
+ if (!value) {
return nullptr;
}
- auto* c = materialize->ConstantValue();
- if (!c) {
- // TODO(crbug.com/tint/1633): Add error message about invalid materialization when
- // location can be an expression.
- return nullptr;
- }
- location = c->As<uint32_t>();
+ location = value.Get();
}
auto* sem = builder_->create<sem::Parameter>(
@@ -799,6 +776,30 @@
return sem;
}
+utils::Result<uint32_t> Resolver::LocationAttribute(const ast::LocationAttribute* attr) {
+ ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "@location value"};
+ TINT_SCOPED_ASSIGNMENT(expr_eval_stage_constraint_, constraint);
+
+ auto* materialized = Materialize(Expression(attr->expr));
+ if (!materialized) {
+ return utils::Failure;
+ }
+
+ if (!materialized->Type()->IsAnyOf<sem::I32, sem::U32>()) {
+ AddError("@location must be an i32 or u32 value", attr->source);
+ return utils::Failure;
+ }
+
+ auto const_value = materialized->ConstantValue();
+ auto value = const_value->As<AInt>();
+ if (value < 0) {
+ AddError("@location value must be non-negative", attr->source);
+ return utils::Failure;
+ }
+
+ return static_cast<uint32_t>(value);
+}
+
ast::Access Resolver::DefaultAccessForAddressSpace(ast::AddressSpace address_space) {
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
switch (address_space) {
@@ -984,18 +985,12 @@
for (auto* attr : decl->return_type_attributes) {
Mark(attr);
- if (auto* a = attr->As<ast::LocationAttribute>()) {
- auto* materialize = Materialize(Expression(a->expr));
- if (!materialize) {
+ if (auto* loc_attr = attr->As<ast::LocationAttribute>()) {
+ auto value = LocationAttribute(loc_attr);
+ if (!value) {
return nullptr;
}
- auto* c = materialize->ConstantValue();
- if (!c) {
- // TODO(crbug.com/tint/1633): Add error message about invalid materialization when
- // location can be an expression.
- return nullptr;
- }
- return_location = c->As<uint32_t>();
+ return_location = value.Get();
}
}
if (!validator_.NoDuplicateAttributes(decl->attributes)) {
@@ -2969,22 +2964,12 @@
has_size_attr = true;
return true;
},
- [&](const ast::LocationAttribute* l) {
- ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant,
- "@location"};
- TINT_SCOPED_ASSIGNMENT(expr_eval_stage_constraint_, constraint);
-
- auto* materialize = Materialize(Expression(l->expr));
- if (!materialize) {
+ [&](const ast::LocationAttribute* loc_attr) {
+ auto value = LocationAttribute(loc_attr);
+ if (!value) {
return false;
}
- auto* c = materialize->ConstantValue();
- if (!c) {
- // TODO(crbug.com/tint/1633): Add error message about invalid
- // materialization when location can be an expression.
- return false;
- }
- location = c->As<uint32_t>();
+ location = value.Get();
return true;
},
[&](Default) {
diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h
index b657b46..89aab13 100644
--- a/src/tint/resolver/resolver.h
+++ b/src/tint/resolver/resolver.h
@@ -349,6 +349,10 @@
/// @param index the index of the parameter
sem::Parameter* Parameter(const ast::Parameter* param, uint32_t index);
+ /// @returns the location value for a `@location` attribute, validating the value's range and
+ /// type.
+ utils::Result<uint32_t> LocationAttribute(const ast::LocationAttribute* attr);
+
/// Records the address space usage for the given type, and any transient
/// dependencies of the type. Validates that the type can be used for the
/// given address space, erroring if it cannot.
diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc
index 831e49e..d5ff803 100644
--- a/src/tint/resolver/uniformity.cc
+++ b/src/tint/resolver/uniformity.cc
@@ -1121,11 +1121,7 @@
v1_cf->AddEdge(v1);
auto [cf2, v2] = ProcessExpression(v1_cf, b->rhs);
-
- if (sem_.Get(b)->Behaviors() == sem::Behaviors{sem::Behavior::kNext}) {
- return std::pair<Node*, Node*>(cf, v2);
- }
- return std::pair<Node*, Node*>(cf2, v2);
+ return std::pair<Node*, Node*>(cf, v2);
} else {
auto [cf1, v1] = ProcessExpression(cf, b->lhs);
auto [cf2, v2] = ProcessExpression(cf1, b->rhs);
diff --git a/src/tint/resolver/uniformity_test.cc b/src/tint/resolver/uniformity_test.cc
index faefb13..fbaeff9 100644
--- a/src/tint/resolver/uniformity_test.cc
+++ b/src/tint/resolver/uniformity_test.cc
@@ -6939,6 +6939,43 @@
)");
}
+TEST_F(UniformityAnalysisTest, ShortCircuiting_UniformLHS) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> uniform_global : i32;
+
+fn main() {
+ let b = (uniform_global == 0) && (dpdx(1.0) == 0.0);
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ShortCircuiting_NonUniformLHS) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+fn main() {
+ let b = (non_uniform_global == 0) && (dpdx(1.0) == 0.0);
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:5:41 warning: 'dpdx' must only be called from uniform control flow
+ let b = (non_uniform_global == 0) && (dpdx(1.0) == 0.0);
+ ^^^^
+
+test:5:37 note: control flow depends on non-uniform value
+ let b = (non_uniform_global == 0) && (dpdx(1.0) == 0.0);
+ ^^
+
+test:5:12 note: reading from read_write storage buffer 'non_uniform_global' may result in a non-uniform value
+ let b = (non_uniform_global == 0) && (dpdx(1.0) == 0.0);
+ ^^^^^^^^^^^^^^^^^^
+)");
+}
+
TEST_F(UniformityAnalysisTest, ShortCircuiting_ReconvergeLHS) {
std::string src = R"(
@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index 7f1cecf..f96af05 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -797,7 +797,7 @@
if (attr->Is<ast::IdAttribute>()) {
auto id = v->OverrideId();
if (auto it = override_ids.find(id); it != override_ids.end() && it->second != v) {
- AddError("override IDs must be unique", attr->source);
+ AddError("@id values must be unique", attr->source);
AddNote("a override with an ID of " + std::to_string(id.value) +
" was previously declared here:",
ast::GetAttribute<ast::IdAttribute>(it->second->Declaration()->attributes)
@@ -1382,6 +1382,14 @@
AddError(std::string(constraint) + " requires " + stage_name(latest_stage) +
", but expression is " + stage_name(expr->Stage()),
expr->Declaration()->source);
+
+ if (auto* stmt = expr->Stmt()) {
+ if (auto* decl = As<ast::VariableDeclStatement>(stmt->Declaration())) {
+ if (decl->variable->Is<ast::Const>()) {
+ AddNote("consider changing 'const' to 'let'", decl->source);
+ }
+ }
+ }
return false;
}
return true;
diff --git a/src/tint/resolver/variable_validation_test.cc b/src/tint/resolver/variable_validation_test.cc
index d302264..964c8d9 100644
--- a/src/tint/resolver/variable_validation_test.cc
+++ b/src/tint/resolver/variable_validation_test.cc
@@ -417,10 +417,8 @@
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
}
-TEST_F(ResolverVariableValidationTest, ConstInitWithVar) {
- auto* v = Var("v", Expr(1_i));
- auto* c = Const("c", Expr(Source{{12, 34}}, v));
- WrapInFunction(v, c);
+TEST_F(ResolverVariableValidationTest, GlobalConstWithRuntimeExpression) {
+ GlobalConst("c", Call(Source{{12, 34}}, "dpdx", 1._a));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -428,47 +426,64 @@
R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression)");
}
+TEST_F(ResolverVariableValidationTest, ConstInitWithVar) {
+ auto* v = Var("v", Expr(1_i));
+ auto* c = Const("c", Expr(Source{{12, 34}}, v));
+ WrapInFunction(v, Decl(Source{{56, 78}}, c));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression
+56:78 note: consider changing 'const' to 'let')");
+}
+
TEST_F(ResolverVariableValidationTest, ConstInitWithOverride) {
auto* o = Override("v", Expr(1_i));
auto* c = Const("c", Expr(Source{{12, 34}}, o));
- WrapInFunction(c);
+ WrapInFunction(Decl(Source{{56, 78}}, c));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: const initializer requires a const-expression, but expression is an override-expression)");
+ R"(12:34 error: const initializer requires a const-expression, but expression is an override-expression
+56:78 note: consider changing 'const' to 'let')");
}
TEST_F(ResolverVariableValidationTest, ConstInitWithLet) {
auto* l = Let("v", Expr(1_i));
auto* c = Const("c", Expr(Source{{12, 34}}, l));
- WrapInFunction(l, c);
+ WrapInFunction(l, Decl(Source{{56, 78}}, c));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression)");
+ R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression
+56:78 note: consider changing 'const' to 'let')");
}
TEST_F(ResolverVariableValidationTest, ConstInitWithRuntimeExpr) {
// const c = clamp(2, dpdx(0.5), 3);
- WrapInFunction(Const("c", Call("clamp", 2_a, Call(Source{{12, 34}}, "dpdx", 0.5_a), 3_a)));
+ auto* c = Const("c", Call("clamp", 2_a, Call(Source{{12, 34}}, "dpdx", 0.5_a), 3_a));
+ WrapInFunction(Decl(Source{{56, 78}}, c));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression)");
+ R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression
+56:78 note: consider changing 'const' to 'let')");
}
TEST_F(ResolverVariableValidationTest, ConstInitWithOverrideExpr) {
auto* o = Override("v", Expr(1_i));
auto* c = Const("c", Add(10_a, Expr(Source{{12, 34}}, o)));
- WrapInFunction(c);
+ WrapInFunction(Decl(Source{{56, 78}}, c));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: const initializer requires a const-expression, but expression is an override-expression)");
+ R"(12:34 error: const initializer requires a const-expression, but expression is an override-expression
+56:78 note: consider changing 'const' to 'let')");
}
} // namespace
diff --git a/src/tint/sem/builtin_type.cc b/src/tint/sem/builtin_type.cc
index d010d89..899fbd3 100644
--- a/src/tint/sem/builtin_type.cc
+++ b/src/tint/sem/builtin_type.cc
@@ -210,6 +210,9 @@
if (name == "pow") {
return BuiltinType::kPow;
}
+ if (name == "quantizeToF16") {
+ return BuiltinType::kQuantizeToF16;
+ }
if (name == "radians") {
return BuiltinType::kRadians;
}
@@ -492,6 +495,8 @@
return "pack4x8unorm";
case BuiltinType::kPow:
return "pow";
+ case BuiltinType::kQuantizeToF16:
+ return "quantizeToF16";
case BuiltinType::kRadians:
return "radians";
case BuiltinType::kReflect:
diff --git a/src/tint/sem/builtin_type.h b/src/tint/sem/builtin_type.h
index 05c2def..0cfc48e 100644
--- a/src/tint/sem/builtin_type.h
+++ b/src/tint/sem/builtin_type.h
@@ -92,6 +92,7 @@
kPack4X8Snorm,
kPack4X8Unorm,
kPow,
+ kQuantizeToF16,
kRadians,
kReflect,
kRefract,
diff --git a/src/tint/sem/variable.h b/src/tint/sem/variable.h
index 8e271d7..634f5da 100644
--- a/src/tint/sem/variable.h
+++ b/src/tint/sem/variable.h
@@ -23,6 +23,7 @@
#include "src/tint/ast/access.h"
#include "src/tint/ast/address_space.h"
+#include "src/tint/ast/parameter.h"
#include "src/tint/sem/binding_point.h"
#include "src/tint/sem/expression.h"
#include "src/tint/sem/parameter_usage.h"
@@ -212,6 +213,11 @@
/// Destructor
~Parameter() override;
+ /// @returns the AST declaration node
+ const ast::Parameter* Declaration() const {
+ return static_cast<const ast::Parameter*>(Variable::Declaration());
+ }
+
/// @return the index of the parmeter in the function
uint32_t Index() const { return index_; }
diff --git a/src/tint/test_main.cc b/src/tint/test_main.cc
index ca68271..918bd20 100644
--- a/src/tint/test_main.cc
+++ b/src/tint/test_main.cc
@@ -14,15 +14,12 @@
#include "gmock/gmock.h"
#include "src/tint/program.h"
+#include "tint/tint.h"
#if TINT_BUILD_SPV_READER
#include "src/tint/reader/spirv/parser_impl_test_helper.h"
#endif
-#if TINT_BUILD_WGSL_WRITER
-#include "src/tint/writer/wgsl/generator.h"
-#endif
-
namespace {
void TintInternalCompilerErrorReporter(const tint::diag::List& diagnostics) {
@@ -54,15 +51,7 @@
int main(int argc, char** argv) {
testing::InitGoogleMock(&argc, argv);
-#if TINT_BUILD_WGSL_WRITER
- tint::Program::printer = [](const tint::Program* program) {
- auto result = tint::writer::wgsl::Generate(program, {});
- if (!result.error.empty()) {
- return "error: " + result.error;
- }
- return result.wgsl;
- };
-#endif // TINT_BUILD_WGSL_WRITER
+ tint::Initialize();
Flags flags;
if (!flags.parse(argc, argv)) {
@@ -79,5 +68,7 @@
auto res = RUN_ALL_TESTS();
+ tint::Shutdown();
+
return res;
}
diff --git a/src/tint/tint.cc b/src/tint/tint.cc
new file mode 100644
index 0000000..cea69cb
--- /dev/null
+++ b/src/tint/tint.cc
@@ -0,0 +1,36 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "tint/tint.h"
+
+namespace tint {
+
+void Initialize() {
+#if TINT_BUILD_WGSL_WRITER
+ // Register the Program printer. This is used for debugging purposes.
+ tint::Program::printer = [](const tint::Program* program) {
+ auto result = writer::wgsl::Generate(program, {});
+ if (!result.error.empty()) {
+ return "error: " + result.error;
+ }
+ return result.wgsl;
+ };
+#endif
+}
+
+void Shutdown() {
+ // Currently no-op, but may release tint resources in the future.
+}
+
+} // namespace tint
diff --git a/src/tint/transform/add_block_attribute.cc b/src/tint/transform/add_block_attribute.cc
index 97c531e..513925f 100644
--- a/src/tint/transform/add_block_attribute.cc
+++ b/src/tint/transform/add_block_attribute.cc
@@ -27,97 +27,78 @@
namespace tint::transform {
-namespace {
-
-bool IsUsedAsNonBuffer(const std::unordered_set<tint::ast::AddressSpace>& uses) {
- for (auto use : uses) {
- if (!ast::IsHostShareable(use)) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace
-
AddBlockAttribute::AddBlockAttribute() = default;
AddBlockAttribute::~AddBlockAttribute() = default;
-void AddBlockAttribute::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- auto& sem = ctx.src->Sem();
+Transform::ApplyResult AddBlockAttribute::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
- // Collect the set of structs that are nested in other types.
- utils::Hashset<const sem::Struct*, 8> nested_structs;
- for (auto* ty : ctx.src->Types()) {
- Switch(
- ty,
- [&](const sem::Array* arr) {
- if (auto* nested_str = arr->ElemType()->As<sem::Struct>()) {
- nested_structs.Add(nested_str);
- }
- },
- [&](const sem::Struct* str) {
- for (auto* member : str->Members()) {
- if (auto* nested_str = member->Type()->As<sem::Struct>()) {
- nested_structs.Add(nested_str);
- }
- }
- });
- }
+ auto& sem = src->Sem();
// A map from a type in the source program to a block-decorated wrapper that contains it in the
// destination program.
utils::Hashmap<const sem::Type*, const ast::Struct*, 8> wrapper_structs;
// Process global 'var' declarations that are buffers.
- for (auto* global : ctx.src->AST().GlobalVariables()) {
+ bool made_changes = false;
+ for (auto* global : src->AST().GlobalVariables()) {
auto* var = sem.Get(global);
if (!ast::IsHostShareable(var->AddressSpace())) {
// Not declared in a host-sharable address space
continue;
}
+ made_changes = true;
+
auto* ty = var->Type()->UnwrapRef();
auto* str = ty->As<sem::Struct>();
- bool needs_wrapping =
- !str || // Type is not a structure
- nested_structs.Contains(str) || // Structure is nested by another type
- IsUsedAsNonBuffer(str->AddressSpaceUsage()); // Structure is used as a non-buffer usage
+
+ // Always try to wrap the buffer type into a struct. We can not do so only if it is a struct
+ // but without a fixed footprint, i.e. contains a runtime-sized array as its member. Note
+ // that such struct type can be only used as storage buffer variables' type. Also note that
+ // any buffer struct type that may be nested by another type must have a fixed footprint,
+ // therefore will be wrapped.
+ bool needs_wrapping = !str || // Type is not a structure
+ str->HasFixedFootprint(); // Struct has a fixed footprint
if (needs_wrapping) {
const char* kMemberName = "inner";
- // This is a non-struct or a struct that is nested somewhere else, so we
- // need to wrap it first.
auto* wrapper = wrapper_structs.GetOrCreate(ty, [&] {
- auto* block = ctx.dst->ASTNodes().Create<BlockAttribute>(ctx.dst->ID(),
- ctx.dst->AllocateNodeID());
- auto wrapper_name = ctx.src->Symbols().NameFor(global->symbol) + "_block";
- auto* ret = ctx.dst->create<ast::Struct>(
- ctx.dst->Symbols().New(wrapper_name),
- utils::Vector{ctx.dst->Member(kMemberName, CreateASTTypeFor(ctx, ty))},
+ auto* block = b.ASTNodes().Create<BlockAttribute>(b.ID(), b.AllocateNodeID());
+ auto wrapper_name = src->Symbols().NameFor(global->symbol) + "_block";
+ auto* ret = b.create<ast::Struct>(
+ b.Symbols().New(wrapper_name),
+ utils::Vector{b.Member(kMemberName, CreateASTTypeFor(ctx, ty))},
utils::Vector{block});
- ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), global, ret);
+ ctx.InsertBefore(src->AST().GlobalDeclarations(), global, ret);
return ret;
});
- ctx.Replace(global->type, ctx.dst->ty.Of(wrapper));
+ ctx.Replace(global->type, b.ty.Of(wrapper));
// Insert a member accessor to get the original type from the wrapper at
// any usage of the original variable.
for (auto* user : var->Users()) {
ctx.Replace(user->Declaration(),
- ctx.dst->MemberAccessor(ctx.Clone(global->symbol), kMemberName));
+ b.MemberAccessor(ctx.Clone(global->symbol), kMemberName));
}
} else {
// Add a block attribute to this struct directly.
- auto* block = ctx.dst->ASTNodes().Create<BlockAttribute>(ctx.dst->ID(),
- ctx.dst->AllocateNodeID());
+ auto* block = b.ASTNodes().Create<BlockAttribute>(b.ID(), b.AllocateNodeID());
ctx.InsertFront(str->Declaration()->attributes, block);
}
}
+ if (!made_changes) {
+ return SkipTransform;
+ }
+
ctx.Clone();
+ return Program(std::move(b));
}
AddBlockAttribute::BlockAttribute::BlockAttribute(ProgramID pid, ast::NodeID nid)
diff --git a/src/tint/transform/add_block_attribute.h b/src/tint/transform/add_block_attribute.h
index 69dfab5..d5e8c4e 100644
--- a/src/tint/transform/add_block_attribute.h
+++ b/src/tint/transform/add_block_attribute.h
@@ -22,11 +22,8 @@
namespace tint::transform {
-/// AddBlockAttribute is a transform that adds an
-/// `@internal(block)` attribute to any structure that is used as the
-/// store type of a buffer. If that structure is nested inside another structure
-/// or an array, then it is wrapped inside another structure which gets the
-/// `@internal(block)` attribute instead.
+/// AddBlockAttribute is a transform that wrap the store type of a buffer into a struct if possible,
+/// then adds an `@internal(block)` attribute to the wrapper struct.
class AddBlockAttribute final : public Castable<AddBlockAttribute, Transform> {
public:
/// BlockAttribute is an InternalAttribute that is used to decorate a
@@ -56,14 +53,10 @@
/// Destructor
~AddBlockAttribute() override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/add_block_attribute_test.cc b/src/tint/transform/add_block_attribute_test.cc
index 7bb5efc..e4519dd 100644
--- a/src/tint/transform/add_block_attribute_test.cc
+++ b/src/tint/transform/add_block_attribute_test.cc
@@ -200,6 +200,85 @@
EXPECT_EQ(expect, str(got));
}
+TEST_F(AddBlockAttributeTest, BasicStruct_Storage_AccessRoot) {
+ auto* src = R"(
+struct S {
+ f : f32,
+};
+
+@group(0) @binding(0)
+var<storage, read_write> s : S;
+
+@fragment
+fn main() {
+ let f = s;
+}
+)";
+ auto* expect = R"(
+struct S {
+ f : f32,
+}
+
+@internal(block)
+struct s_block {
+ inner : S,
+}
+
+@group(0) @binding(0) var<storage, read_write> s : s_block;
+
+@fragment
+fn main() {
+ let f = s.inner;
+}
+)";
+
+ auto got = Run<AddBlockAttribute>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(AddBlockAttributeTest, BasicStruct_Storage_TwoUsage_AccessRoot) {
+ auto* src = R"(
+struct S {
+ f : f32,
+};
+
+@group(0) @binding(0)
+var<storage, read_write> in : S;
+
+@group(0) @binding(1)
+var<storage, read_write> out : S;
+
+@compute @workgroup_size(1)
+fn main() {
+ out = in;
+}
+)";
+ auto* expect = R"(
+struct S {
+ f : f32,
+}
+
+@internal(block)
+struct in_block {
+ inner : S,
+}
+
+@group(0) @binding(0) var<storage, read_write> in : in_block;
+
+@group(0) @binding(1) var<storage, read_write> out : in_block;
+
+@compute @workgroup_size(1)
+fn main() {
+ out.inner = in.inner;
+}
+)";
+
+ auto got = Run<AddBlockAttribute>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
TEST_F(AddBlockAttributeTest, BasicStruct_AccessField) {
auto* src = R"(
struct S {
@@ -215,16 +294,20 @@
}
)";
auto* expect = R"(
-@internal(block)
struct S {
f : f32,
}
-@group(0) @binding(0) var<uniform> u : S;
+@internal(block)
+struct u_block {
+ inner : S,
+}
+
+@group(0) @binding(0) var<uniform> u : u_block;
@fragment
fn main() {
- let f = u.f;
+ let f = u.inner.f;
}
)";
@@ -280,16 +363,20 @@
auto* expect = R"(
enable chromium_experimental_push_constant;
-@internal(block)
struct S {
f : f32,
}
-var<push_constant> u : S;
+@internal(block)
+struct u_block {
+ inner : S,
+}
+
+var<push_constant> u : u_block;
@fragment
fn main() {
- let f = u.f;
+ let f = u.inner.f;
}
)";
@@ -321,16 +408,20 @@
f : f32,
}
-@internal(block)
struct Outer {
i : Inner,
}
-@group(0) @binding(0) var<uniform> u : Outer;
+@internal(block)
+struct u_block {
+ inner : Outer,
+}
+
+@group(0) @binding(0) var<uniform> u : u_block;
@fragment
fn main() {
- let f = u.i.f;
+ let f = u.inner.i.f;
}
)";
@@ -366,12 +457,16 @@
f : f32,
}
-@internal(block)
struct Outer {
i : Inner,
}
-@group(0) @binding(0) var<uniform> u0 : Outer;
+@internal(block)
+struct u0_block {
+ inner : Outer,
+}
+
+@group(0) @binding(0) var<uniform> u0 : u0_block;
@internal(block)
struct u1_block {
@@ -382,7 +477,7 @@
@fragment
fn main() {
- let f0 = u0.i.f;
+ let f0 = u0.inner.i.f;
let f1 = u1.inner.f;
}
)";
@@ -474,12 +569,16 @@
f : f32,
}
-@internal(block)
struct S {
i : Inner,
}
-@group(0) @binding(0) var<uniform> u0 : S;
+@internal(block)
+struct u0_block {
+ inner : S,
+}
+
+@group(0) @binding(0) var<uniform> u0 : u0_block;
@internal(block)
struct u1_block {
@@ -492,7 +591,7 @@
@fragment
fn main() {
- let f0 = u0.i.f;
+ let f0 = u0.inner.i.f;
let f1 = u1.inner.f;
let f2 = u2.inner.f;
}
@@ -621,14 +720,18 @@
type MyInner = Inner;
-@internal(block)
struct Outer {
i : MyInner,
}
type MyOuter = Outer;
-@group(0) @binding(0) var<uniform> u0 : MyOuter;
+@internal(block)
+struct u0_block {
+ inner : Outer,
+}
+
+@group(0) @binding(0) var<uniform> u0 : u0_block;
@internal(block)
struct u1_block {
@@ -639,7 +742,7 @@
@fragment
fn main() {
- let f0 = u0.i.f;
+ let f0 = u0.inner.i.f;
let f1 = u1.inner.f;
}
)";
@@ -678,7 +781,7 @@
auto* expect = R"(
@fragment
fn main() {
- let f0 = u0.i.f;
+ let f0 = u0.inner.i.f;
let f1 = u1.inner.f;
}
@@ -691,11 +794,15 @@
type MyInner = Inner;
-@group(0) @binding(0) var<uniform> u0 : MyOuter;
+@internal(block)
+struct u0_block {
+ inner : Outer,
+}
+
+@group(0) @binding(0) var<uniform> u0 : u0_block;
type MyOuter = Outer;
-@internal(block)
struct Outer {
i : MyInner,
}
@@ -810,18 +917,22 @@
}
)";
auto* expect = R"(
-@internal(block) @internal(block)
struct S {
f : f32,
}
-@group(0) @binding(0) var<uniform> u : S;
+@internal(block)
+struct u_block {
+ inner : S,
+}
-@group(0) @binding(1) var<storage, read_write> s : S;
+@group(0) @binding(0) var<uniform> u : u_block;
+
+@group(0) @binding(1) var<storage, read_write> s : u_block;
@fragment
fn main() {
- s = u;
+ s.inner = u.inner;
}
)";
@@ -850,5 +961,65 @@
EXPECT_EQ(expect, str(got));
}
+TEST_F(AddBlockAttributeTest, StorageBufferWithRuntimeArray) {
+ auto* src = R"(
+struct S {
+ f : f32,
+}
+
+struct SWithArr {
+ f : f32,
+ arr : array<f32>,
+}
+
+@group(0) @binding(0)
+var<storage, read> in_1 : S;
+
+@group(0) @binding(1)
+var<storage, read> in_2 : SWithArr;
+
+@group(1) @binding(0)
+var<storage, read_write> out : SWithArr;
+
+@fragment
+fn main() {
+ out.f = in_1.f;
+ out.arr[0] = in_2.arr[1];
+}
+)";
+ auto* expect = R"(
+struct S {
+ f : f32,
+}
+
+@internal(block) @internal(block)
+struct SWithArr {
+ f : f32,
+ arr : array<f32>,
+}
+
+@internal(block)
+struct in_1_block {
+ inner : S,
+}
+
+@group(0) @binding(0) var<storage, read> in_1 : in_1_block;
+
+@group(0) @binding(1) var<storage, read> in_2 : SWithArr;
+
+@group(1) @binding(0) var<storage, read_write> out : SWithArr;
+
+@fragment
+fn main() {
+ out.f = in_1.inner.f;
+ out.arr[0] = in_2.arr[1];
+}
+)";
+
+ auto got = Run<AddBlockAttribute>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
} // namespace
} // namespace tint::transform
diff --git a/src/tint/transform/add_empty_entry_point.cc b/src/tint/transform/add_empty_entry_point.cc
index 5ef4fe8..f71394d 100644
--- a/src/tint/transform/add_empty_entry_point.cc
+++ b/src/tint/transform/add_empty_entry_point.cc
@@ -23,12 +23,9 @@
using namespace tint::number_suffixes; // NOLINT
namespace tint::transform {
+namespace {
-AddEmptyEntryPoint::AddEmptyEntryPoint() = default;
-
-AddEmptyEntryPoint::~AddEmptyEntryPoint() = default;
-
-bool AddEmptyEntryPoint::ShouldRun(const Program* program, const DataMap&) const {
+bool ShouldRun(const Program* program) {
for (auto* func : program->AST().Functions()) {
if (func->IsEntryPoint()) {
return false;
@@ -37,13 +34,30 @@
return true;
}
-void AddEmptyEntryPoint::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- ctx.dst->Func(ctx.dst->Symbols().New("unused_entry_point"), {}, ctx.dst->ty.void_(), {},
- utils::Vector{
- ctx.dst->Stage(ast::PipelineStage::kCompute),
- ctx.dst->WorkgroupSize(1_i),
- });
+} // namespace
+
+AddEmptyEntryPoint::AddEmptyEntryPoint() = default;
+
+AddEmptyEntryPoint::~AddEmptyEntryPoint() = default;
+
+Transform::ApplyResult AddEmptyEntryPoint::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
+ }
+
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
+ b.Func(b.Symbols().New("unused_entry_point"), {}, b.ty.void_(), {},
+ utils::Vector{
+ b.Stage(ast::PipelineStage::kCompute),
+ b.WorkgroupSize(1_i),
+ });
+
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/add_empty_entry_point.h b/src/tint/transform/add_empty_entry_point.h
index 5530355..828f3b5 100644
--- a/src/tint/transform/add_empty_entry_point.h
+++ b/src/tint/transform/add_empty_entry_point.h
@@ -27,19 +27,10 @@
/// Destructor
~AddEmptyEntryPoint() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/array_length_from_uniform.cc b/src/tint/transform/array_length_from_uniform.cc
index 3938b0c..70097f2 100644
--- a/src/tint/transform/array_length_from_uniform.cc
+++ b/src/tint/transform/array_length_from_uniform.cc
@@ -31,13 +31,153 @@
namespace tint::transform {
+namespace {
+
+bool ShouldRun(const Program* program) {
+ for (auto* fn : program->AST().Functions()) {
+ if (auto* sem_fn = program->Sem().Get(fn)) {
+ for (auto* builtin : sem_fn->DirectlyCalledBuiltins()) {
+ if (builtin->Type() == sem::BuiltinType::kArrayLength) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+} // namespace
+
ArrayLengthFromUniform::ArrayLengthFromUniform() = default;
ArrayLengthFromUniform::~ArrayLengthFromUniform() = default;
-/// The PIMPL state for this transform
+/// PIMPL state for the transform
struct ArrayLengthFromUniform::State {
+ /// Constructor
+ /// @param program the source program
+ /// @param in the input transform data
+ /// @param out the output transform data
+ explicit State(const Program* program, const DataMap& in, DataMap& out)
+ : src(program), inputs(in), outputs(out) {}
+
+ /// Runs the transform
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
+ auto* cfg = inputs.Get<Config>();
+ if (cfg == nullptr) {
+ b.Diagnostics().add_error(diag::System::Transform,
+ "missing transform data for " +
+ std::string(TypeInfo::Of<ArrayLengthFromUniform>().name));
+ return Program(std::move(b));
+ }
+
+ if (!ShouldRun(ctx.src)) {
+ return SkipTransform;
+ }
+
+ const char* kBufferSizeMemberName = "buffer_size";
+
+ // Determine the size of the buffer size array.
+ uint32_t max_buffer_size_index = 0;
+
+ IterateArrayLengthOnStorageVar([&](const ast::CallExpression*, const sem::VariableUser*,
+ const sem::GlobalVariable* var) {
+ auto binding = var->BindingPoint();
+ auto idx_itr = cfg->bindpoint_to_size_index.find(binding);
+ if (idx_itr == cfg->bindpoint_to_size_index.end()) {
+ return;
+ }
+ if (idx_itr->second > max_buffer_size_index) {
+ max_buffer_size_index = idx_itr->second;
+ }
+ });
+
+ // Get (or create, on first call) the uniform buffer that will receive the
+ // size of each storage buffer in the module.
+ const ast::Variable* buffer_size_ubo = nullptr;
+ auto get_ubo = [&]() {
+ if (!buffer_size_ubo) {
+ // Emit an array<vec4<u32>, N>, where N is 1/4 number of elements.
+ // We do this because UBOs require an element stride that is 16-byte
+ // aligned.
+ auto* buffer_size_struct = b.Structure(
+ b.Sym(), utils::Vector{
+ b.Member(kBufferSizeMemberName,
+ b.ty.array(b.ty.vec4(b.ty.u32()),
+ u32((max_buffer_size_index / 4) + 1))),
+ });
+ buffer_size_ubo =
+ b.GlobalVar(b.Sym(), b.ty.Of(buffer_size_struct), ast::AddressSpace::kUniform,
+ b.Group(AInt(cfg->ubo_binding.group)),
+ b.Binding(AInt(cfg->ubo_binding.binding)));
+ }
+ return buffer_size_ubo;
+ };
+
+ std::unordered_set<uint32_t> used_size_indices;
+
+ IterateArrayLengthOnStorageVar([&](const ast::CallExpression* call_expr,
+ const sem::VariableUser* storage_buffer_sem,
+ const sem::GlobalVariable* var) {
+ auto binding = var->BindingPoint();
+ auto idx_itr = cfg->bindpoint_to_size_index.find(binding);
+ if (idx_itr == cfg->bindpoint_to_size_index.end()) {
+ return;
+ }
+
+ uint32_t size_index = idx_itr->second;
+ used_size_indices.insert(size_index);
+
+ // Load the total storage buffer size from the UBO.
+ uint32_t array_index = size_index / 4;
+ auto* vec_expr = b.IndexAccessor(
+ b.MemberAccessor(get_ubo()->symbol, kBufferSizeMemberName), u32(array_index));
+ uint32_t vec_index = size_index % 4;
+ auto* total_storage_buffer_size = b.IndexAccessor(vec_expr, u32(vec_index));
+
+ // Calculate actual array length
+ // total_storage_buffer_size - array_offset
+ // array_length = ----------------------------------------
+ // array_stride
+ const ast::Expression* total_size = total_storage_buffer_size;
+ auto* storage_buffer_type = storage_buffer_sem->Type()->UnwrapRef();
+ const sem::Array* array_type = nullptr;
+ if (auto* str = storage_buffer_type->As<sem::Struct>()) {
+ // The variable is a struct, so subtract the byte offset of the array
+ // member.
+ auto* array_member_sem = str->Members().back();
+ array_type = array_member_sem->Type()->As<sem::Array>();
+ total_size = b.Sub(total_storage_buffer_size, u32(array_member_sem->Offset()));
+ } else if (auto* arr = storage_buffer_type->As<sem::Array>()) {
+ array_type = arr;
+ } else {
+ TINT_ICE(Transform, b.Diagnostics())
+ << "expected form of arrayLength argument to be &array_var or "
+ "&struct_var.array_member";
+ return;
+ }
+ auto* array_length = b.Div(total_size, u32(array_type->Stride()));
+
+ ctx.Replace(call_expr, array_length);
+ });
+
+ outputs.Add<Result>(used_size_indices);
+
+ ctx.Clone();
+ return Program(std::move(b));
+ }
+
+ private:
+ /// The source program
+ const Program* const src;
+ /// The transform inputs
+ const DataMap& inputs;
+ /// The transform outputs
+ DataMap& outputs;
+ /// The target program builder
+ ProgramBuilder b;
/// The clone context
- CloneContext& ctx;
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
/// Iterate over all arrayLength() builtins that operate on
/// storage buffer variables.
@@ -48,10 +188,10 @@
/// sem::GlobalVariable for the storage buffer.
template <typename F>
void IterateArrayLengthOnStorageVar(F&& functor) {
- auto& sem = ctx.src->Sem();
+ auto& sem = src->Sem();
// Find all calls to the arrayLength() builtin.
- for (auto* node : ctx.src->ASTNodes().Objects()) {
+ for (auto* node : src->ASTNodes().Objects()) {
auto* call_expr = node->As<ast::CallExpression>();
if (!call_expr) {
continue;
@@ -79,7 +219,7 @@
// arrayLength(&array_var)
auto* param = call_expr->args[0]->As<ast::UnaryOpExpression>();
if (!param || param->op != ast::UnaryOp::kAddressOf) {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "expected form of arrayLength argument to be &array_var or "
"&struct_var.array_member";
break;
@@ -90,7 +230,7 @@
}
auto* storage_buffer_sem = sem.Get<sem::VariableUser>(storage_buffer_expr);
if (!storage_buffer_sem) {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "expected form of arrayLength argument to be &array_var or "
"&struct_var.array_member";
break;
@@ -99,8 +239,7 @@
// Get the index to use for the buffer size array.
auto* var = tint::As<sem::GlobalVariable>(storage_buffer_sem->Variable());
if (!var) {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
- << "storage buffer is not a global variable";
+ TINT_ICE(Transform, b.Diagnostics()) << "storage buffer is not a global variable";
break;
}
functor(call_expr, storage_buffer_sem, var);
@@ -108,117 +247,10 @@
}
};
-bool ArrayLengthFromUniform::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* fn : program->AST().Functions()) {
- if (auto* sem_fn = program->Sem().Get(fn)) {
- for (auto* builtin : sem_fn->DirectlyCalledBuiltins()) {
- if (builtin->Type() == sem::BuiltinType::kArrayLength) {
- return true;
- }
- }
- }
- }
- return false;
-}
-
-void ArrayLengthFromUniform::Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const {
- auto* cfg = inputs.Get<Config>();
- if (cfg == nullptr) {
- ctx.dst->Diagnostics().add_error(
- diag::System::Transform, "missing transform data for " + std::string(TypeInfo().name));
- return;
- }
-
- const char* kBufferSizeMemberName = "buffer_size";
-
- // Determine the size of the buffer size array.
- uint32_t max_buffer_size_index = 0;
-
- State{ctx}.IterateArrayLengthOnStorageVar(
- [&](const ast::CallExpression*, const sem::VariableUser*, const sem::GlobalVariable* var) {
- auto binding = var->BindingPoint();
- auto idx_itr = cfg->bindpoint_to_size_index.find(binding);
- if (idx_itr == cfg->bindpoint_to_size_index.end()) {
- return;
- }
- if (idx_itr->second > max_buffer_size_index) {
- max_buffer_size_index = idx_itr->second;
- }
- });
-
- // Get (or create, on first call) the uniform buffer that will receive the
- // size of each storage buffer in the module.
- const ast::Variable* buffer_size_ubo = nullptr;
- auto get_ubo = [&]() {
- if (!buffer_size_ubo) {
- // Emit an array<vec4<u32>, N>, where N is 1/4 number of elements.
- // We do this because UBOs require an element stride that is 16-byte
- // aligned.
- auto* buffer_size_struct = ctx.dst->Structure(
- ctx.dst->Sym(),
- utils::Vector{
- ctx.dst->Member(kBufferSizeMemberName,
- ctx.dst->ty.array(ctx.dst->ty.vec4(ctx.dst->ty.u32()),
- u32((max_buffer_size_index / 4) + 1))),
- });
- buffer_size_ubo = ctx.dst->GlobalVar(ctx.dst->Sym(), ctx.dst->ty.Of(buffer_size_struct),
- ast::AddressSpace::kUniform,
- ctx.dst->Group(AInt(cfg->ubo_binding.group)),
- ctx.dst->Binding(AInt(cfg->ubo_binding.binding)));
- }
- return buffer_size_ubo;
- };
-
- std::unordered_set<uint32_t> used_size_indices;
-
- State{ctx}.IterateArrayLengthOnStorageVar([&](const ast::CallExpression* call_expr,
- const sem::VariableUser* storage_buffer_sem,
- const sem::GlobalVariable* var) {
- auto binding = var->BindingPoint();
- auto idx_itr = cfg->bindpoint_to_size_index.find(binding);
- if (idx_itr == cfg->bindpoint_to_size_index.end()) {
- return;
- }
-
- uint32_t size_index = idx_itr->second;
- used_size_indices.insert(size_index);
-
- // Load the total storage buffer size from the UBO.
- uint32_t array_index = size_index / 4;
- auto* vec_expr = ctx.dst->IndexAccessor(
- ctx.dst->MemberAccessor(get_ubo()->symbol, kBufferSizeMemberName), u32(array_index));
- uint32_t vec_index = size_index % 4;
- auto* total_storage_buffer_size = ctx.dst->IndexAccessor(vec_expr, u32(vec_index));
-
- // Calculate actual array length
- // total_storage_buffer_size - array_offset
- // array_length = ----------------------------------------
- // array_stride
- const ast::Expression* total_size = total_storage_buffer_size;
- auto* storage_buffer_type = storage_buffer_sem->Type()->UnwrapRef();
- const sem::Array* array_type = nullptr;
- if (auto* str = storage_buffer_type->As<sem::Struct>()) {
- // The variable is a struct, so subtract the byte offset of the array
- // member.
- auto* array_member_sem = str->Members().back();
- array_type = array_member_sem->Type()->As<sem::Array>();
- total_size = ctx.dst->Sub(total_storage_buffer_size, u32(array_member_sem->Offset()));
- } else if (auto* arr = storage_buffer_type->As<sem::Array>()) {
- array_type = arr;
- } else {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
- << "expected form of arrayLength argument to be &array_var or "
- "&struct_var.array_member";
- return;
- }
- auto* array_length = ctx.dst->Div(total_size, u32(array_type->Stride()));
-
- ctx.Replace(call_expr, array_length);
- });
-
- ctx.Clone();
-
- outputs.Add<Result>(used_size_indices);
+Transform::ApplyResult ArrayLengthFromUniform::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap& outputs) const {
+ return State{src, inputs, outputs}.Run();
}
ArrayLengthFromUniform::Config::Config(sem::BindingPoint ubo_bp) : ubo_binding(ubo_bp) {}
diff --git a/src/tint/transform/array_length_from_uniform.h b/src/tint/transform/array_length_from_uniform.h
index 8bd6af5..507ea37 100644
--- a/src/tint/transform/array_length_from_uniform.h
+++ b/src/tint/transform/array_length_from_uniform.h
@@ -100,22 +100,12 @@
std::unordered_set<uint32_t> used_size_indices;
};
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
private:
- /// The PIMPL state for this transform
struct State;
};
diff --git a/src/tint/transform/array_length_from_uniform_test.cc b/src/tint/transform/array_length_from_uniform_test.cc
index 1058bf1..b5d9e77 100644
--- a/src/tint/transform/array_length_from_uniform_test.cc
+++ b/src/tint/transform/array_length_from_uniform_test.cc
@@ -28,7 +28,13 @@
TEST_F(ArrayLengthFromUniformTest, ShouldRunEmptyModule) {
auto* src = R"()";
- EXPECT_FALSE(ShouldRun<ArrayLengthFromUniform>(src));
+ ArrayLengthFromUniform::Config cfg({0, 30u});
+ cfg.bindpoint_to_size_index.emplace(sem::BindingPoint{0, 0}, 0);
+
+ DataMap data;
+ data.Add<ArrayLengthFromUniform::Config>(std::move(cfg));
+
+ EXPECT_FALSE(ShouldRun<ArrayLengthFromUniform>(src, data));
}
TEST_F(ArrayLengthFromUniformTest, ShouldRunNoArrayLength) {
@@ -45,7 +51,13 @@
}
)";
- EXPECT_FALSE(ShouldRun<ArrayLengthFromUniform>(src));
+ ArrayLengthFromUniform::Config cfg({0, 30u});
+ cfg.bindpoint_to_size_index.emplace(sem::BindingPoint{0, 0}, 0);
+
+ DataMap data;
+ data.Add<ArrayLengthFromUniform::Config>(std::move(cfg));
+
+ EXPECT_FALSE(ShouldRun<ArrayLengthFromUniform>(src, data));
}
TEST_F(ArrayLengthFromUniformTest, ShouldRunWithArrayLength) {
@@ -63,7 +75,13 @@
}
)";
- EXPECT_TRUE(ShouldRun<ArrayLengthFromUniform>(src));
+ ArrayLengthFromUniform::Config cfg({0, 30u});
+ cfg.bindpoint_to_size_index.emplace(sem::BindingPoint{0, 0}, 0);
+
+ DataMap data;
+ data.Add<ArrayLengthFromUniform::Config>(std::move(cfg));
+
+ EXPECT_TRUE(ShouldRun<ArrayLengthFromUniform>(src, data));
}
TEST_F(ArrayLengthFromUniformTest, Error_MissingTransformData) {
diff --git a/src/tint/transform/binding_remapper.cc b/src/tint/transform/binding_remapper.cc
index 798b228..0781355 100644
--- a/src/tint/transform/binding_remapper.cc
+++ b/src/tint/transform/binding_remapper.cc
@@ -40,19 +40,21 @@
BindingRemapper::BindingRemapper() = default;
BindingRemapper::~BindingRemapper() = default;
-bool BindingRemapper::ShouldRun(const Program*, const DataMap& inputs) const {
- if (auto* remappings = inputs.Get<Remappings>()) {
- return !remappings->binding_points.empty() || !remappings->access_controls.empty();
- }
- return false;
-}
+Transform::ApplyResult BindingRemapper::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
-void BindingRemapper::Run(CloneContext& ctx, const DataMap& inputs, DataMap&) const {
auto* remappings = inputs.Get<Remappings>();
if (!remappings) {
- ctx.dst->Diagnostics().add_error(
- diag::System::Transform, "missing transform data for " + std::string(TypeInfo().name));
- return;
+ b.Diagnostics().add_error(diag::System::Transform,
+ "missing transform data for " + std::string(TypeInfo().name));
+ return Program(std::move(b));
+ }
+
+ if (remappings->binding_points.empty() && remappings->access_controls.empty()) {
+ return SkipTransform;
}
// A set of post-remapped binding points that need to be decorated with a
@@ -62,11 +64,11 @@
if (remappings->allow_collisions) {
// Scan for binding point collisions generated by this transform.
// Populate all collisions in the `add_collision_attr` set.
- for (auto* func_ast : ctx.src->AST().Functions()) {
+ for (auto* func_ast : src->AST().Functions()) {
if (!func_ast->IsEntryPoint()) {
continue;
}
- auto* func = ctx.src->Sem().Get(func_ast);
+ auto* func = src->Sem().Get(func_ast);
std::unordered_map<sem::BindingPoint, int> binding_point_counts;
for (auto* global : func->TransitivelyReferencedGlobals()) {
if (global->Declaration()->HasBindingPoint()) {
@@ -90,9 +92,9 @@
}
}
- for (auto* var : ctx.src->AST().Globals<ast::Var>()) {
+ for (auto* var : src->AST().Globals<ast::Var>()) {
if (var->HasBindingPoint()) {
- auto* global_sem = ctx.src->Sem().Get<sem::GlobalVariable>(var);
+ auto* global_sem = src->Sem().Get<sem::GlobalVariable>(var);
// The original binding point
BindingPoint from = global_sem->BindingPoint();
@@ -106,8 +108,8 @@
auto bp_it = remappings->binding_points.find(from);
if (bp_it != remappings->binding_points.end()) {
BindingPoint to = bp_it->second;
- auto* new_group = ctx.dst->Group(AInt(to.group));
- auto* new_binding = ctx.dst->Binding(AInt(to.binding));
+ auto* new_group = b.Group(AInt(to.group));
+ auto* new_binding = b.Binding(AInt(to.binding));
auto* old_group = ast::GetAttribute<ast::GroupAttribute>(var->attributes);
auto* old_binding = ast::GetAttribute<ast::BindingAttribute>(var->attributes);
@@ -122,37 +124,37 @@
if (ac_it != remappings->access_controls.end()) {
ast::Access ac = ac_it->second;
if (ac == ast::Access::kUndefined) {
- ctx.dst->Diagnostics().add_error(
+ b.Diagnostics().add_error(
diag::System::Transform,
"invalid access mode (" + std::to_string(static_cast<uint32_t>(ac)) + ")");
- return;
+ return Program(std::move(b));
}
- auto* sem = ctx.src->Sem().Get(var);
+ auto* sem = src->Sem().Get(var);
if (sem->AddressSpace() != ast::AddressSpace::kStorage) {
- ctx.dst->Diagnostics().add_error(
+ b.Diagnostics().add_error(
diag::System::Transform,
"cannot apply access control to variable with address space " +
std::string(utils::ToString(sem->AddressSpace())));
- return;
+ return Program(std::move(b));
}
auto* ty = sem->Type()->UnwrapRef();
const ast::Type* inner_ty = CreateASTTypeFor(ctx, ty);
- auto* new_var =
- ctx.dst->Var(ctx.Clone(var->source), ctx.Clone(var->symbol), inner_ty,
- var->declared_address_space, ac, ctx.Clone(var->initializer),
- ctx.Clone(var->attributes));
+ auto* new_var = b.Var(ctx.Clone(var->source), ctx.Clone(var->symbol), inner_ty,
+ var->declared_address_space, ac, ctx.Clone(var->initializer),
+ ctx.Clone(var->attributes));
ctx.Replace(var, new_var);
}
// Add `DisableValidationAttribute`s if required
if (add_collision_attr.count(bp)) {
- auto* attribute = ctx.dst->Disable(ast::DisabledValidation::kBindingPointCollision);
+ auto* attribute = b.Disable(ast::DisabledValidation::kBindingPointCollision);
ctx.InsertBefore(var->attributes, *var->attributes.begin(), attribute);
}
}
}
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/binding_remapper.h b/src/tint/transform/binding_remapper.h
index 77fc5bc..b0efe0d 100644
--- a/src/tint/transform/binding_remapper.h
+++ b/src/tint/transform/binding_remapper.h
@@ -67,19 +67,10 @@
BindingRemapper();
~BindingRemapper() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/binding_remapper_test.cc b/src/tint/transform/binding_remapper_test.cc
index 564a3a5..5bafb7e 100644
--- a/src/tint/transform/binding_remapper_test.cc
+++ b/src/tint/transform/binding_remapper_test.cc
@@ -23,12 +23,6 @@
using BindingRemapperTest = TransformTest;
-TEST_F(BindingRemapperTest, ShouldRunNoRemappings) {
- auto* src = R"()";
-
- EXPECT_FALSE(ShouldRun<BindingRemapper>(src));
-}
-
TEST_F(BindingRemapperTest, ShouldRunEmptyRemappings) {
auto* src = R"()";
@@ -350,7 +344,7 @@
}
)";
- auto* expect = src;
+ auto* expect = R"(error: missing transform data for tint::transform::BindingRemapper)";
auto got = Run<BindingRemapper>(src);
diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc
index ec00672..e80436d 100644
--- a/src/tint/transform/builtin_polyfill.cc
+++ b/src/tint/transform/builtin_polyfill.cc
@@ -29,7 +29,7 @@
namespace tint::transform {
-/// The PIMPL state for the BuiltinPolyfill transform
+/// PIMPL state for the transform
struct BuiltinPolyfill::State {
/// Constructor
/// @param c the CloneContext
@@ -556,6 +556,27 @@
return name;
}
+ /// Builds the polyfill function for the `quantizeToF16` builtin, by replacing the vector form
+ /// with scalar calls.
+ /// @param vec the vector type
+ /// @return the polyfill function name
+ Symbol quantizeToF16(const sem::Vector* vec) {
+ auto name = b.Symbols().New("tint_quantizeToF16");
+ utils::Vector<const ast::Expression*, 4> args;
+ for (uint32_t i = 0; i < vec->Width(); i++) {
+ args.Push(b.Call("quantizeToF16", b.IndexAccessor("v", u32(i))));
+ }
+ b.Func(name,
+ utils::Vector{
+ b.Param("v", T(vec)),
+ },
+ T(vec),
+ utils::Vector{
+ b.Return(b.Construct(T(vec), std::move(args))),
+ });
+ return name;
+ }
+
private:
/// @returns the AST type for the given sem type
const ast::Type* T(const sem::Type* ty) const { return CreateASTTypeFor(ctx, ty); }
@@ -583,213 +604,165 @@
BuiltinPolyfill::~BuiltinPolyfill() = default;
-bool BuiltinPolyfill::ShouldRun(const Program* program, const DataMap& data) const {
- if (auto* cfg = data.Get<Config>()) {
- auto builtins = cfg->builtins;
- auto& sem = program->Sem();
- for (auto* node : program->ASTNodes().Objects()) {
- if (auto* call = sem.Get<sem::Call>(node)) {
- if (auto* builtin = call->Target()->As<sem::Builtin>()) {
- if (call->Stage() == sem::EvaluationStage::kConstant) {
- continue; // Don't polyfill @const expressions
- }
- switch (builtin->Type()) {
- case sem::BuiltinType::kAcosh:
- if (builtins.acosh != Level::kNone) {
- return true;
- }
- break;
- case sem::BuiltinType::kAsinh:
- if (builtins.asinh) {
- return true;
- }
- break;
- case sem::BuiltinType::kAtanh:
- if (builtins.atanh != Level::kNone) {
- return true;
- }
- break;
- case sem::BuiltinType::kClamp:
- if (builtins.clamp_int) {
- auto& sig = builtin->Signature();
- return sig.parameters[0]->Type()->is_integer_scalar_or_vector();
- }
- break;
- case sem::BuiltinType::kCountLeadingZeros:
- if (builtins.count_leading_zeros) {
- return true;
- }
- break;
- case sem::BuiltinType::kCountTrailingZeros:
- if (builtins.count_trailing_zeros) {
- return true;
- }
- break;
- case sem::BuiltinType::kExtractBits:
- if (builtins.extract_bits != Level::kNone) {
- return true;
- }
- break;
- case sem::BuiltinType::kFirstLeadingBit:
- if (builtins.first_leading_bit) {
- return true;
- }
- break;
- case sem::BuiltinType::kFirstTrailingBit:
- if (builtins.first_trailing_bit) {
- return true;
- }
- break;
- case sem::BuiltinType::kInsertBits:
- if (builtins.insert_bits != Level::kNone) {
- return true;
- }
- break;
- case sem::BuiltinType::kSaturate:
- if (builtins.saturate) {
- return true;
- }
- break;
- case sem::BuiltinType::kTextureSampleBaseClampToEdge:
- if (builtins.texture_sample_base_clamp_to_edge_2d_f32) {
- auto& sig = builtin->Signature();
- auto* tex = sig.Parameter(sem::ParameterUsage::kTexture);
- if (auto* stex = tex->Type()->As<sem::SampledTexture>()) {
- return stex->type()->Is<sem::F32>();
- }
- }
- break;
- default:
- break;
- }
- }
- }
- }
- }
- return false;
-}
-
-void BuiltinPolyfill::Run(CloneContext& ctx, const DataMap& data, DataMap&) const {
+Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src,
+ const DataMap& data,
+ DataMap&) const {
auto* cfg = data.Get<Config>();
if (!cfg) {
- ctx.Clone();
- return;
+ return SkipTransform;
}
- std::unordered_map<const sem::Builtin*, Symbol> polyfills;
+ auto& builtins = cfg->builtins;
- ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::CallExpression* {
- auto builtins = cfg->builtins;
- State s{ctx, builtins};
- if (auto* call = s.sem.Get<sem::Call>(expr)) {
- if (auto* builtin = call->Target()->As<sem::Builtin>()) {
- if (call->Stage() == sem::EvaluationStage::kConstant) {
- return nullptr; // Don't polyfill @const expressions
- }
- Symbol polyfill;
- switch (builtin->Type()) {
- case sem::BuiltinType::kAcosh:
- if (builtins.acosh != Level::kNone) {
- polyfill = utils::GetOrCreate(
- polyfills, builtin, [&] { return s.acosh(builtin->ReturnType()); });
+ utils::Hashmap<const sem::Builtin*, Symbol, 8> builtin_polyfills;
+
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+ State s{ctx, builtins};
+
+ bool made_changes = false;
+ for (auto* node : src->ASTNodes().Objects()) {
+ auto* expr = src->Sem().Get<sem::Expression>(node);
+ if (!expr || expr->Stage() == sem::EvaluationStage::kConstant) {
+ continue; // Don't polyfill @const expressions
+ }
+
+ if (auto* call = expr->As<sem::Call>()) {
+ auto* builtin = call->Target()->As<sem::Builtin>();
+ if (!builtin) {
+ continue;
+ }
+ Symbol polyfill;
+ switch (builtin->Type()) {
+ case sem::BuiltinType::kAcosh:
+ if (builtins.acosh != Level::kNone) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.acosh(builtin->ReturnType()); });
+ }
+ break;
+ case sem::BuiltinType::kAsinh:
+ if (builtins.asinh) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.asinh(builtin->ReturnType()); });
+ }
+ break;
+ case sem::BuiltinType::kAtanh:
+ if (builtins.atanh != Level::kNone) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.atanh(builtin->ReturnType()); });
+ }
+ break;
+ case sem::BuiltinType::kClamp:
+ if (builtins.clamp_int) {
+ auto& sig = builtin->Signature();
+ if (sig.parameters[0]->Type()->is_integer_scalar_or_vector()) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.clampInteger(builtin->ReturnType()); });
}
- break;
- case sem::BuiltinType::kAsinh:
- if (builtins.asinh) {
- polyfill = utils::GetOrCreate(
- polyfills, builtin, [&] { return s.asinh(builtin->ReturnType()); });
- }
- break;
- case sem::BuiltinType::kAtanh:
- if (builtins.atanh != Level::kNone) {
- polyfill = utils::GetOrCreate(
- polyfills, builtin, [&] { return s.atanh(builtin->ReturnType()); });
- }
- break;
- case sem::BuiltinType::kClamp:
- if (builtins.clamp_int) {
- auto& sig = builtin->Signature();
- if (sig.parameters[0]->Type()->is_integer_scalar_or_vector()) {
- polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
- return s.clampInteger(builtin->ReturnType());
+ }
+ break;
+ case sem::BuiltinType::kCountLeadingZeros:
+ if (builtins.count_leading_zeros) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.countLeadingZeros(builtin->ReturnType()); });
+ }
+ break;
+ case sem::BuiltinType::kCountTrailingZeros:
+ if (builtins.count_trailing_zeros) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.countTrailingZeros(builtin->ReturnType()); });
+ }
+ break;
+ case sem::BuiltinType::kExtractBits:
+ if (builtins.extract_bits != Level::kNone) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.extractBits(builtin->ReturnType()); });
+ }
+ break;
+ case sem::BuiltinType::kFirstLeadingBit:
+ if (builtins.first_leading_bit) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.firstLeadingBit(builtin->ReturnType()); });
+ }
+ break;
+ case sem::BuiltinType::kFirstTrailingBit:
+ if (builtins.first_trailing_bit) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.firstTrailingBit(builtin->ReturnType()); });
+ }
+ break;
+ case sem::BuiltinType::kInsertBits:
+ if (builtins.insert_bits != Level::kNone) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.insertBits(builtin->ReturnType()); });
+ }
+ break;
+ case sem::BuiltinType::kSaturate:
+ if (builtins.saturate) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.saturate(builtin->ReturnType()); });
+ }
+ break;
+ case sem::BuiltinType::kTextureSampleBaseClampToEdge:
+ if (builtins.texture_sample_base_clamp_to_edge_2d_f32) {
+ auto& sig = builtin->Signature();
+ auto* tex = sig.Parameter(sem::ParameterUsage::kTexture);
+ if (auto* stex = tex->Type()->As<sem::SampledTexture>()) {
+ if (stex->type()->Is<sem::F32>()) {
+ polyfill = builtin_polyfills.GetOrCreate(builtin, [&] {
+ return s.textureSampleBaseClampToEdge_2d_f32();
});
}
}
- break;
- case sem::BuiltinType::kCountLeadingZeros:
- if (builtins.count_leading_zeros) {
- polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
- return s.countLeadingZeros(builtin->ReturnType());
- });
+ }
+ break;
+ case sem::BuiltinType::kQuantizeToF16:
+ if (builtins.quantize_to_vec_f16) {
+ if (auto* vec = builtin->ReturnType()->As<sem::Vector>()) {
+ polyfill = builtin_polyfills.GetOrCreate(
+ builtin, [&] { return s.quantizeToF16(vec); });
}
- break;
- case sem::BuiltinType::kCountTrailingZeros:
- if (builtins.count_trailing_zeros) {
- polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
- return s.countTrailingZeros(builtin->ReturnType());
- });
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (polyfill.IsValid()) {
+ auto* replacement = s.b.Call(polyfill, ctx.Clone(call->Declaration()->args));
+ ctx.Replace(call->Declaration(), replacement);
+ made_changes = true;
+ }
+ } else if (auto* bin_op = node->As<ast::BinaryExpression>()) {
+ switch (bin_op->op) {
+ case ast::BinaryOp::kShiftLeft:
+ case ast::BinaryOp::kShiftRight:
+ if (builtins.bitshift_modulo) {
+ auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef();
+ auto* rhs_ty = src->TypeOf(bin_op->rhs)->UnwrapRef();
+ auto* lhs_el_ty = sem::Type::DeepestElementOf(lhs_ty);
+ const ast::Expression* mask = b.Expr(AInt(lhs_el_ty->Size() * 8 - 1));
+ if (rhs_ty->Is<sem::Vector>()) {
+ mask = b.Construct(CreateASTTypeFor(ctx, rhs_ty), mask);
}
- break;
- case sem::BuiltinType::kExtractBits:
- if (builtins.extract_bits != Level::kNone) {
- polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
- return s.extractBits(builtin->ReturnType());
- });
- }
- break;
- case sem::BuiltinType::kFirstLeadingBit:
- if (builtins.first_leading_bit) {
- polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
- return s.firstLeadingBit(builtin->ReturnType());
- });
- }
- break;
- case sem::BuiltinType::kFirstTrailingBit:
- if (builtins.first_trailing_bit) {
- polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
- return s.firstTrailingBit(builtin->ReturnType());
- });
- }
- break;
- case sem::BuiltinType::kInsertBits:
- if (builtins.insert_bits != Level::kNone) {
- polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
- return s.insertBits(builtin->ReturnType());
- });
- }
- break;
- case sem::BuiltinType::kSaturate:
- if (builtins.saturate) {
- polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
- return s.saturate(builtin->ReturnType());
- });
- }
- break;
- case sem::BuiltinType::kTextureSampleBaseClampToEdge:
- if (builtins.texture_sample_base_clamp_to_edge_2d_f32) {
- auto& sig = builtin->Signature();
- auto* tex = sig.Parameter(sem::ParameterUsage::kTexture);
- if (auto* stex = tex->Type()->As<sem::SampledTexture>()) {
- if (stex->type()->Is<sem::F32>()) {
- polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
- return s.textureSampleBaseClampToEdge_2d_f32();
- });
- }
- }
- }
- break;
- default:
- break;
- }
- if (polyfill.IsValid()) {
- return s.b.Call(polyfill, ctx.Clone(call->Declaration()->args));
- }
+ auto* mod = b.And(ctx.Clone(bin_op->rhs), mask);
+ ctx.Replace(bin_op->rhs, mod);
+ made_changes = true;
+ }
+ break;
+ default:
+ break;
}
}
- return nullptr;
- });
+ }
+
+ if (!made_changes) {
+ return SkipTransform;
+ }
ctx.Clone();
+ return Program(std::move(b));
}
BuiltinPolyfill::Config::Config(const Builtins& b) : builtins(b) {}
diff --git a/src/tint/transform/builtin_polyfill.h b/src/tint/transform/builtin_polyfill.h
index d083252..7083aa7 100644
--- a/src/tint/transform/builtin_polyfill.h
+++ b/src/tint/transform/builtin_polyfill.h
@@ -47,6 +47,8 @@
bool asinh = false;
/// What level should `atanh` be polyfilled?
Level atanh = Level::kNone;
+ /// Should the RHS of `<<` and `>>` be wrapped in a modulo bit-width of LHS?
+ bool bitshift_modulo = false;
/// Should `clamp()` be polyfilled for integer values (scalar or vector)?
bool clamp_int = false;
/// Should `countLeadingZeros()` be polyfilled?
@@ -65,6 +67,9 @@
bool saturate = false;
/// Should `textureSampleBaseClampToEdge()` be polyfilled for texture_2d<f32> textures?
bool texture_sample_base_clamp_to_edge_2d_f32 = false;
+ /// Should the vector form of `quantizeToF16()` be polyfilled with a scalar implementation?
+ /// See crbug.com/tint/1741
+ bool quantize_to_vec_f16 = false;
};
/// Config is consumed by the BuiltinPolyfill transform.
@@ -84,21 +89,13 @@
const Builtins builtins;
};
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- protected:
+ private:
struct State;
-
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/builtin_polyfill_test.cc b/src/tint/transform/builtin_polyfill_test.cc
index b938195..3b7a42c 100644
--- a/src/tint/transform/builtin_polyfill_test.cc
+++ b/src/tint/transform/builtin_polyfill_test.cc
@@ -399,6 +399,145 @@
}
////////////////////////////////////////////////////////////////////////////////
+// bitshiftModulo
+////////////////////////////////////////////////////////////////////////////////
+DataMap polyfillBitshiftModulo() {
+ BuiltinPolyfill::Builtins builtins;
+ builtins.bitshift_modulo = true;
+ DataMap data;
+ data.Add<BuiltinPolyfill::Config>(builtins);
+ return data;
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunBitshiftModulo_shl_scalar) {
+ auto* src = R"(
+fn f() {
+ let v = 15u;
+ let r = 1i << v;
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillBitshiftModulo()));
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunBitshiftModulo_shl_vector) {
+ auto* src = R"(
+fn f() {
+ let v = 15u;
+ let r = vec3(1i) << vec3(v);
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillBitshiftModulo()));
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunBitshiftModulo_shr_scalar) {
+ auto* src = R"(
+fn f() {
+ let v = 15u;
+ let r = 1i >> v;
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillBitshiftModulo()));
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunBitshiftModulo_shr_vector) {
+ auto* src = R"(
+fn f() {
+ let v = 15u;
+ let r = vec3(1i) >> vec3(v);
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillBitshiftModulo()));
+}
+
+TEST_F(BuiltinPolyfillTest, BitshiftModulo_shl_scalar) {
+ auto* src = R"(
+fn f() {
+ let v = 15u;
+ let r = 1i << v;
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ let v = 15u;
+ let r = (1i << (v & 31));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillBitshiftModulo());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, BitshiftModulo_shl_vector) {
+ auto* src = R"(
+fn f() {
+ let v = 15u;
+ let r = vec3(1i) << vec3(v);
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ let v = 15u;
+ let r = (vec3(1i) << (vec3(v) & vec3<u32>(31)));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillBitshiftModulo());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, BitshiftModulo_shr_scalar) {
+ auto* src = R"(
+fn f() {
+ let v = 15u;
+ let r = 1i >> v;
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ let v = 15u;
+ let r = (1i >> (v & 31));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillBitshiftModulo());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, BitshiftModulo_shr_vector) {
+ auto* src = R"(
+fn f() {
+ let v = 15u;
+ let r = vec3(1i) >> vec3(v);
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ let v = 15u;
+ let r = (vec3(1i) >> (vec3(v) & vec3<u32>(31)));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillBitshiftModulo());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+////////////////////////////////////////////////////////////////////////////////
// clampInteger
////////////////////////////////////////////////////////////////////////////////
DataMap polyfillClampInteger() {
@@ -1561,7 +1700,8 @@
TEST_F(BuiltinPolyfillTest, DISABLED_InsertBits_ConstantExpression) {
auto* src = R"(
fn f() {
- let r : i32 = insertBits(1234, 5678, 5u, 6u);
+ let v = 1234i;
+ let r : i32 = insertBits(v, 5678, 5u, 6u);
}
)";
@@ -1975,10 +2115,6 @@
)";
auto* expect = R"(
-@group(0) @binding(0) var t : texture_2d<f32>;
-
-@group(0) @binding(1) var s : sampler;
-
fn tint_textureSampleBaseClampToEdge(t : texture_2d<f32>, s : sampler, coord : vec2<f32>) -> vec4<f32> {
let dims = vec2<f32>(textureDimensions(t, 0));
let half_texel = (vec2<f32>(0.5) / dims);
@@ -1986,6 +2122,10 @@
return textureSampleLevel(t, s, clamped, 0);
}
+@group(0) @binding(0) var t : texture_2d<f32>;
+
+@group(0) @binding(1) var s : sampler;
+
fn f() {
let r = tint_textureSampleBaseClampToEdge(t, s, vec2<f32>(0.5));
}
@@ -1996,5 +2136,112 @@
EXPECT_EQ(expect, str(got));
}
+////////////////////////////////////////////////////////////////////////////////
+// quantizeToF16
+////////////////////////////////////////////////////////////////////////////////
+DataMap polyfillQuantizeToF16_2d_f32() {
+ BuiltinPolyfill::Builtins builtins;
+ builtins.quantize_to_vec_f16 = true;
+ DataMap data;
+ data.Add<BuiltinPolyfill::Config>(builtins);
+ return data;
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunQuantizeToF16_Scalar) {
+ auto* src = R"(
+fn f() {
+ let v = 0.5;
+ quantizeToF16(0.5);
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src, polyfillQuantizeToF16_2d_f32()));
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunQuantizeToF16_Vector) {
+ auto* src = R"(
+fn f() {
+ let v = 0.5;
+ quantizeToF16(vec2(v));
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillQuantizeToF16_2d_f32()));
+}
+
+TEST_F(BuiltinPolyfillTest, QuantizeToF16_Vec2) {
+ auto* src = R"(
+fn f() {
+ let v = 0.5;
+ quantizeToF16(vec2(v));
+}
+)";
+
+ auto* expect = R"(
+fn tint_quantizeToF16(v : vec2<f32>) -> vec2<f32> {
+ return vec2<f32>(quantizeToF16(v[0u]), quantizeToF16(v[1u]));
+}
+
+fn f() {
+ let v = 0.5;
+ tint_quantizeToF16(vec2(v));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillQuantizeToF16_2d_f32());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, QuantizeToF16_Vec3) {
+ auto* src = R"(
+fn f() {
+ let v = 0.5;
+ quantizeToF16(vec3(v));
+}
+)";
+
+ auto* expect = R"(
+fn tint_quantizeToF16(v : vec3<f32>) -> vec3<f32> {
+ return vec3<f32>(quantizeToF16(v[0u]), quantizeToF16(v[1u]), quantizeToF16(v[2u]));
+}
+
+fn f() {
+ let v = 0.5;
+ tint_quantizeToF16(vec3(v));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillQuantizeToF16_2d_f32());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, QuantizeToF16_Vec4) {
+ auto* src = R"(
+fn f() {
+ let v = 0.5;
+ quantizeToF16(vec4(v));
+}
+)";
+
+ auto* expect = R"(
+fn tint_quantizeToF16(v : vec4<f32>) -> vec4<f32> {
+ return vec4<f32>(quantizeToF16(v[0u]), quantizeToF16(v[1u]), quantizeToF16(v[2u]), quantizeToF16(v[3u]));
+}
+
+fn f() {
+ let v = 0.5;
+ tint_quantizeToF16(vec4(v));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillQuantizeToF16_2d_f32());
+
+ EXPECT_EQ(expect, str(got));
+}
+
} // namespace
} // namespace tint::transform
diff --git a/src/tint/transform/calculate_array_length.cc b/src/tint/transform/calculate_array_length.cc
index 2ca5e54..9dcdd7b 100644
--- a/src/tint/transform/calculate_array_length.cc
+++ b/src/tint/transform/calculate_array_length.cc
@@ -40,6 +40,19 @@
namespace {
+bool ShouldRun(const Program* program) {
+ for (auto* fn : program->AST().Functions()) {
+ if (auto* sem_fn = program->Sem().Get(fn)) {
+ for (auto* builtin : sem_fn->DirectlyCalledBuiltins()) {
+ if (builtin->Type() == sem::BuiltinType::kArrayLength) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
/// ArrayUsage describes a runtime array usage.
/// It is used as a key by the array_length_by_usage map.
struct ArrayUsage {
@@ -73,21 +86,16 @@
CalculateArrayLength::CalculateArrayLength() = default;
CalculateArrayLength::~CalculateArrayLength() = default;
-bool CalculateArrayLength::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* fn : program->AST().Functions()) {
- if (auto* sem_fn = program->Sem().Get(fn)) {
- for (auto* builtin : sem_fn->DirectlyCalledBuiltins()) {
- if (builtin->Type() == sem::BuiltinType::kArrayLength) {
- return true;
- }
- }
- }
+Transform::ApplyResult CalculateArrayLength::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
}
- return false;
-}
-void CalculateArrayLength::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- auto& sem = ctx.src->Sem();
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+ auto& sem = src->Sem();
// get_buffer_size_intrinsic() emits the function decorated with
// BufferSizeIntrinsic that is transformed by the HLSL writer into a call to
@@ -95,24 +103,20 @@
std::unordered_map<const sem::Reference*, Symbol> buffer_size_intrinsics;
auto get_buffer_size_intrinsic = [&](const sem::Reference* buffer_type) {
return utils::GetOrCreate(buffer_size_intrinsics, buffer_type, [&] {
- auto name = ctx.dst->Sym();
+ auto name = b.Sym();
auto* type = CreateASTTypeFor(ctx, buffer_type);
- auto* disable_validation =
- ctx.dst->Disable(ast::DisabledValidation::kFunctionParameter);
- ctx.dst->AST().AddFunction(ctx.dst->create<ast::Function>(
+ auto* disable_validation = b.Disable(ast::DisabledValidation::kFunctionParameter);
+ b.AST().AddFunction(b.create<ast::Function>(
name,
utils::Vector{
- ctx.dst->Param("buffer",
- ctx.dst->ty.pointer(type, buffer_type->AddressSpace(),
- buffer_type->Access()),
- utils::Vector{disable_validation}),
- ctx.dst->Param("result", ctx.dst->ty.pointer(ctx.dst->ty.u32(),
- ast::AddressSpace::kFunction)),
+ b.Param("buffer",
+ b.ty.pointer(type, buffer_type->AddressSpace(), buffer_type->Access()),
+ utils::Vector{disable_validation}),
+ b.Param("result", b.ty.pointer(b.ty.u32(), ast::AddressSpace::kFunction)),
},
- ctx.dst->ty.void_(), nullptr,
+ b.ty.void_(), nullptr,
utils::Vector{
- ctx.dst->ASTNodes().Create<BufferSizeIntrinsic>(ctx.dst->ID(),
- ctx.dst->AllocateNodeID()),
+ b.ASTNodes().Create<BufferSizeIntrinsic>(b.ID(), b.AllocateNodeID()),
},
utils::Empty));
@@ -123,7 +127,7 @@
std::unordered_map<ArrayUsage, Symbol, ArrayUsage::Hasher> array_length_by_usage;
// Find all the arrayLength() calls...
- for (auto* node : ctx.src->ASTNodes().Objects()) {
+ for (auto* node : src->ASTNodes().Objects()) {
if (auto* call_expr = node->As<ast::CallExpression>()) {
auto* call = sem.Get(call_expr)->UnwrapMaterialize()->As<sem::Call>();
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
@@ -149,7 +153,7 @@
auto* arg = call_expr->args[0];
auto* address_of = arg->As<ast::UnaryOpExpression>();
if (!address_of || address_of->op != ast::UnaryOp::kAddressOf) {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "arrayLength() expected address-of, got " << arg->TypeInfo().name;
}
auto* storage_buffer_expr = address_of->expr;
@@ -158,7 +162,7 @@
}
auto* storage_buffer_sem = sem.Get<sem::VariableUser>(storage_buffer_expr);
if (!storage_buffer_sem) {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "expected form of arrayLength argument to be &array_var or "
"&struct_var.array_member";
break;
@@ -179,25 +183,24 @@
// Construct the variable that'll hold the result of
// RWByteAddressBuffer.GetDimensions()
- auto* buffer_size_result = ctx.dst->Decl(ctx.dst->Var(
- ctx.dst->Sym(), ctx.dst->ty.u32(), ctx.dst->Expr(0_u)));
+ auto* buffer_size_result =
+ b.Decl(b.Var(b.Sym(), b.ty.u32(), b.Expr(0_u)));
// Call storage_buffer.GetDimensions(&buffer_size_result)
- auto* call_get_dims = ctx.dst->CallStmt(ctx.dst->Call(
+ auto* call_get_dims = b.CallStmt(b.Call(
// BufferSizeIntrinsic(X, ARGS...) is
// translated to:
// X.GetDimensions(ARGS..) by the writer
- buffer_size, ctx.dst->AddressOf(ctx.Clone(storage_buffer_expr)),
- ctx.dst->AddressOf(
- ctx.dst->Expr(buffer_size_result->variable->symbol))));
+ buffer_size, b.AddressOf(ctx.Clone(storage_buffer_expr)),
+ b.AddressOf(b.Expr(buffer_size_result->variable->symbol))));
// Calculate actual array length
// total_storage_buffer_size - array_offset
// array_length = ----------------------------------------
// array_stride
- auto name = ctx.dst->Sym();
+ auto name = b.Sym();
const ast::Expression* total_size =
- ctx.dst->Expr(buffer_size_result->variable);
+ b.Expr(buffer_size_result->variable);
const sem::Array* array_type = Switch(
storage_buffer_type->StoreType(),
@@ -205,23 +208,21 @@
// The variable is a struct, so subtract the byte offset of
// the array member.
auto* array_member_sem = str->Members().back();
- total_size =
- ctx.dst->Sub(total_size, u32(array_member_sem->Offset()));
+ total_size = b.Sub(total_size, u32(array_member_sem->Offset()));
return array_member_sem->Type()->As<sem::Array>();
},
[&](const sem::Array* arr) { return arr; });
if (!array_type) {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "expected form of arrayLength argument to be "
"&array_var or &struct_var.array_member";
return name;
}
uint32_t array_stride = array_type->Size();
- auto* array_length_var = ctx.dst->Decl(
- ctx.dst->Let(name, ctx.dst->ty.u32(),
- ctx.dst->Div(total_size, u32(array_stride))));
+ auto* array_length_var = b.Decl(
+ b.Let(name, b.ty.u32(), b.Div(total_size, u32(array_stride))));
// Insert the array length calculations at the top of the block
ctx.InsertBefore(block->statements, block->statements[0],
@@ -234,13 +235,14 @@
});
// Replace the call to arrayLength() with the array length variable
- ctx.Replace(call_expr, ctx.dst->Expr(array_length));
+ ctx.Replace(call_expr, b.Expr(array_length));
}
}
}
}
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/calculate_array_length.h b/src/tint/transform/calculate_array_length.h
index 8db8dcc..e5714a8 100644
--- a/src/tint/transform/calculate_array_length.h
+++ b/src/tint/transform/calculate_array_length.h
@@ -59,19 +59,10 @@
/// Destructor
~CalculateArrayLength() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/canonicalize_entry_point_io.cc b/src/tint/transform/canonicalize_entry_point_io.cc
index b990965..8a14fb7 100644
--- a/src/tint/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/transform/canonicalize_entry_point_io.cc
@@ -123,7 +123,7 @@
} // namespace
-/// State holds the current transform state for a single entry point.
+/// PIMPL state for the transform
struct CanonicalizeEntryPointIO::State {
/// OutputValue represents a shader result that the wrapper function produces.
struct OutputValue {
@@ -770,17 +770,22 @@
}
};
-void CanonicalizeEntryPointIO::Run(CloneContext& ctx, const DataMap& inputs, DataMap&) const {
+Transform::ApplyResult CanonicalizeEntryPointIO::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
auto* cfg = inputs.Get<Config>();
if (cfg == nullptr) {
- ctx.dst->Diagnostics().add_error(
- diag::System::Transform, "missing transform data for " + std::string(TypeInfo().name));
- return;
+ b.Diagnostics().add_error(diag::System::Transform,
+ "missing transform data for " + std::string(TypeInfo().name));
+ return Program(std::move(b));
}
// Remove entry point IO attributes from struct declarations.
// New structures will be created for each entry point, as necessary.
- for (auto* ty : ctx.src->AST().TypeDecls()) {
+ for (auto* ty : src->AST().TypeDecls()) {
if (auto* struct_ty = ty->As<ast::Struct>()) {
for (auto* member : struct_ty->members) {
for (auto* attr : member->attributes) {
@@ -792,7 +797,7 @@
}
}
- for (auto* func_ast : ctx.src->AST().Functions()) {
+ for (auto* func_ast : src->AST().Functions()) {
if (!func_ast->IsEntryPoint()) {
continue;
}
@@ -802,6 +807,7 @@
}
ctx.Clone();
+ return Program(std::move(b));
}
CanonicalizeEntryPointIO::Config::Config(ShaderStyle style,
diff --git a/src/tint/transform/canonicalize_entry_point_io.h b/src/tint/transform/canonicalize_entry_point_io.h
index 95f8b19..fbfed5e 100644
--- a/src/tint/transform/canonicalize_entry_point_io.h
+++ b/src/tint/transform/canonicalize_entry_point_io.h
@@ -127,15 +127,12 @@
CanonicalizeEntryPointIO();
~CanonicalizeEntryPointIO() override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
+ private:
struct State;
};
diff --git a/src/tint/transform/clamp_frag_depth.cc b/src/tint/transform/clamp_frag_depth.cc
index e67dda3..4551925 100644
--- a/src/tint/transform/clamp_frag_depth.cc
+++ b/src/tint/transform/clamp_frag_depth.cc
@@ -14,7 +14,7 @@
#include "src/tint/transform/clamp_frag_depth.h"
- #include <utility>
+#include <utility>
#include "src/tint/ast/attribute.h"
#include "src/tint/ast/builtin_attribute.h"
@@ -64,12 +64,7 @@
return false;
}
-} // anonymous namespace
-
-ClampFragDepth::ClampFragDepth() = default;
-ClampFragDepth::~ClampFragDepth() = default;
-
-bool ClampFragDepth::ShouldRun(const Program* program, const DataMap&) const {
+bool ShouldRun(const Program* program) {
auto& sem = program->Sem();
for (auto* fn : program->AST().Functions()) {
@@ -82,22 +77,33 @@
return false;
}
-void ClampFragDepth::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+} // anonymous namespace
+
+ClampFragDepth::ClampFragDepth() = default;
+ClampFragDepth::~ClampFragDepth() = default;
+
+Transform::ApplyResult ClampFragDepth::Apply(const Program* src, const DataMap&, DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
// Abort on any use of push constants in the module.
- for (auto* global : ctx.src->AST().GlobalVariables()) {
+ for (auto* global : src->AST().GlobalVariables()) {
if (auto* var = global->As<ast::Var>()) {
if (var->declared_address_space == ast::AddressSpace::kPushConstant) {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "ClampFragDepth doesn't know how to handle module that already use push "
"constants.";
- return;
+ return Program(std::move(b));
}
}
}
- auto& b = *ctx.dst;
- auto& sem = ctx.src->Sem();
- auto& sym = ctx.src->Symbols();
+ if (!ShouldRun(src)) {
+ return SkipTransform;
+ }
+
+ auto& sem = src->Sem();
+ auto& sym = src->Symbols();
// At least one entry-point needs clamping. Add the following to the module:
//
@@ -197,6 +203,7 @@
});
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/clamp_frag_depth.h b/src/tint/transform/clamp_frag_depth.h
index 3b15f11..1e9d0d6 100644
--- a/src/tint/transform/clamp_frag_depth.h
+++ b/src/tint/transform/clamp_frag_depth.h
@@ -61,19 +61,10 @@
/// Destructor
~ClampFragDepth() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/combine_samplers.cc b/src/tint/transform/combine_samplers.cc
index 97650ad..e7286d4 100644
--- a/src/tint/transform/combine_samplers.cc
+++ b/src/tint/transform/combine_samplers.cc
@@ -47,10 +47,14 @@
CombineSamplers::BindingInfo::BindingInfo(const BindingInfo& other) = default;
CombineSamplers::BindingInfo::~BindingInfo() = default;
-/// The PIMPL state for the CombineSamplers transform
+/// PIMPL state for the transform
struct CombineSamplers::State {
+ /// The source program
+ const Program* const src;
+ /// The target program builder
+ ProgramBuilder b;
/// The clone context
- CloneContext& ctx;
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
/// The binding info
const BindingInfo* binding_info;
@@ -88,9 +92,9 @@
}
/// Constructor
- /// @param context the clone context
+ /// @param program the source program
/// @param info the binding map information
- State(CloneContext& context, const BindingInfo* info) : ctx(context), binding_info(info) {}
+ State(const Program* program, const BindingInfo* info) : src(program), binding_info(info) {}
/// Creates a combined sampler global variables.
/// (Note this is actually a Texture node at the AST level, but it will be
@@ -145,8 +149,9 @@
}
}
- /// Performs the transformation
- void Run() {
+ /// Runs the transform
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
auto& sem = ctx.src->Sem();
// Remove all texture and sampler global variables. These will be replaced
@@ -169,14 +174,14 @@
// Rewrite all function signatures to use combined samplers, and remove
// separate textures & samplers. Create new combined globals where found.
- ctx.ReplaceAll([&](const ast::Function* src) -> const ast::Function* {
- if (auto* func = sem.Get(src)) {
- auto pairs = func->TextureSamplerPairs();
+ ctx.ReplaceAll([&](const ast::Function* ast_fn) -> const ast::Function* {
+ if (auto* fn = sem.Get(ast_fn)) {
+ auto pairs = fn->TextureSamplerPairs();
if (pairs.IsEmpty()) {
return nullptr;
}
utils::Vector<const ast::Parameter*, 8> params;
- for (auto pair : func->TextureSamplerPairs()) {
+ for (auto pair : fn->TextureSamplerPairs()) {
const sem::Variable* texture_var = pair.first;
const sem::Variable* sampler_var = pair.second;
std::string name =
@@ -197,23 +202,23 @@
auto* type = CreateCombinedASTTypeFor(texture_var, sampler_var);
auto* var = ctx.dst->Param(ctx.dst->Symbols().New(name), type);
params.Push(var);
- function_combined_texture_samplers_[func][pair] = var;
+ function_combined_texture_samplers_[fn][pair] = var;
}
}
// Filter out separate textures and samplers from the original
// function signature.
- for (auto* var : src->params) {
- if (!sem.Get(var->type)->IsAnyOf<sem::Texture, sem::Sampler>()) {
- params.Push(ctx.Clone(var));
+ for (auto* param : fn->Parameters()) {
+ if (!param->Type()->IsAnyOf<sem::Texture, sem::Sampler>()) {
+ params.Push(ctx.Clone(param->Declaration()));
}
}
// Create a new function signature that differs only in the parameter
// list.
- auto symbol = ctx.Clone(src->symbol);
- auto* return_type = ctx.Clone(src->return_type);
- auto* body = ctx.Clone(src->body);
- auto attributes = ctx.Clone(src->attributes);
- auto return_type_attributes = ctx.Clone(src->return_type_attributes);
+ auto symbol = ctx.Clone(ast_fn->symbol);
+ auto* return_type = ctx.Clone(ast_fn->return_type);
+ auto* body = ctx.Clone(ast_fn->body);
+ auto attributes = ctx.Clone(ast_fn->attributes);
+ auto return_type_attributes = ctx.Clone(ast_fn->return_type_attributes);
return ctx.dst->create<ast::Function>(symbol, params, return_type, body,
std::move(attributes),
std::move(return_type_attributes));
@@ -327,6 +332,7 @@
});
ctx.Clone();
+ return Program(std::move(b));
}
};
@@ -334,15 +340,18 @@
CombineSamplers::~CombineSamplers() = default;
-void CombineSamplers::Run(CloneContext& ctx, const DataMap& inputs, DataMap&) const {
+Transform::ApplyResult CombineSamplers::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap&) const {
auto* binding_info = inputs.Get<BindingInfo>();
if (!binding_info) {
- ctx.dst->Diagnostics().add_error(
- diag::System::Transform, "missing transform data for " + std::string(TypeInfo().name));
- return;
+ ProgramBuilder b;
+ b.Diagnostics().add_error(diag::System::Transform,
+ "missing transform data for " + std::string(TypeInfo().name));
+ return Program(std::move(b));
}
- State(ctx, binding_info).Run();
+ return State(src, binding_info).Run();
}
} // namespace tint::transform
diff --git a/src/tint/transform/combine_samplers.h b/src/tint/transform/combine_samplers.h
index 8dfc098..6834abe 100644
--- a/src/tint/transform/combine_samplers.h
+++ b/src/tint/transform/combine_samplers.h
@@ -88,17 +88,13 @@
/// Destructor
~CombineSamplers() override;
- protected:
- /// The PIMPL state for this transform
- struct State;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ private:
+ struct State;
};
} // namespace tint::transform
diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc
index 68324af..046583e 100644
--- a/src/tint/transform/decompose_memory_access.cc
+++ b/src/tint/transform/decompose_memory_access.cc
@@ -47,6 +47,18 @@
namespace {
+bool ShouldRun(const Program* program) {
+ for (auto* decl : program->AST().GlobalDeclarations()) {
+ if (auto* var = program->Sem().Get<sem::Variable>(decl)) {
+ if (var->AddressSpace() == ast::AddressSpace::kStorage ||
+ var->AddressSpace() == ast::AddressSpace::kUniform) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/// Offset is a simple ast::Expression builder interface, used to build byte
/// offsets for storage and uniform buffer accesses.
struct Offset : Castable<Offset> {
@@ -291,7 +303,7 @@
} // namespace
-/// State holds the current transform state
+/// PIMPL state for the transform
struct DecomposeMemoryAccess::State {
/// The clone context
CloneContext& ctx;
@@ -477,7 +489,7 @@
// * Override-expression counts can only be applied to workgroup arrays, and
// this method only handles storage and uniform.
// * Runtime-sized arrays are not loadable.
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "unexpected non-constant array count";
arr_cnt = 1;
}
@@ -578,7 +590,7 @@
// * Override-expression counts can only be applied to workgroup
// arrays, and this method only handles storage and uniform.
// * Runtime-sized arrays are not storable.
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "unexpected non-constant array count";
arr_cnt = 1;
}
@@ -808,21 +820,16 @@
DecomposeMemoryAccess::DecomposeMemoryAccess() = default;
DecomposeMemoryAccess::~DecomposeMemoryAccess() = default;
-bool DecomposeMemoryAccess::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* decl : program->AST().GlobalDeclarations()) {
- if (auto* var = program->Sem().Get<sem::Variable>(decl)) {
- if (var->AddressSpace() == ast::AddressSpace::kStorage ||
- var->AddressSpace() == ast::AddressSpace::kUniform) {
- return true;
- }
- }
+Transform::ApplyResult DecomposeMemoryAccess::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
}
- return false;
-}
-void DecomposeMemoryAccess::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- auto& sem = ctx.src->Sem();
-
+ auto& sem = src->Sem();
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
State state(ctx);
// Scan the AST nodes for storage and uniform buffer accesses. Complex
@@ -833,7 +840,7 @@
// Inner-most expression nodes are guaranteed to be visited first because AST
// nodes are fully immutable and require their children to be constructed
// first so their pointer can be passed to the parent's initializer.
- for (auto* node : ctx.src->ASTNodes().Objects()) {
+ for (auto* node : src->ASTNodes().Objects()) {
if (auto* ident = node->As<ast::IdentifierExpression>()) {
// X
if (auto* var = sem.Get<sem::VariableUser>(ident)) {
@@ -1001,6 +1008,7 @@
}
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/decompose_memory_access.h b/src/tint/transform/decompose_memory_access.h
index 2e92a3a..21c196b 100644
--- a/src/tint/transform/decompose_memory_access.h
+++ b/src/tint/transform/decompose_memory_access.h
@@ -108,20 +108,12 @@
/// Destructor
~DecomposeMemoryAccess() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
-
+ private:
struct State;
};
diff --git a/src/tint/transform/decompose_strided_array.cc b/src/tint/transform/decompose_strided_array.cc
index e9f51a5..73a6629 100644
--- a/src/tint/transform/decompose_strided_array.cc
+++ b/src/tint/transform/decompose_strided_array.cc
@@ -34,13 +34,7 @@
using DecomposedArrays = std::unordered_map<const sem::Array*, Symbol>;
-} // namespace
-
-DecomposeStridedArray::DecomposeStridedArray() = default;
-
-DecomposeStridedArray::~DecomposeStridedArray() = default;
-
-bool DecomposeStridedArray::ShouldRun(const Program* program, const DataMap&) const {
+bool ShouldRun(const Program* program) {
for (auto* node : program->ASTNodes().Objects()) {
if (auto* ast = node->As<ast::Array>()) {
if (ast::GetAttribute<ast::StrideAttribute>(ast->attributes)) {
@@ -51,8 +45,22 @@
return false;
}
-void DecomposeStridedArray::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- const auto& sem = ctx.src->Sem();
+} // namespace
+
+DecomposeStridedArray::DecomposeStridedArray() = default;
+
+DecomposeStridedArray::~DecomposeStridedArray() = default;
+
+Transform::ApplyResult DecomposeStridedArray::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
+ }
+
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+ const auto& sem = src->Sem();
static constexpr const char* kMemberName = "el";
@@ -69,23 +77,23 @@
if (auto* arr = sem.Get(ast)) {
if (!arr->IsStrideImplicit()) {
auto el_ty = utils::GetOrCreate(decomposed, arr, [&] {
- auto name = ctx.dst->Symbols().New("strided_arr");
+ auto name = b.Symbols().New("strided_arr");
auto* member_ty = ctx.Clone(ast->type);
- auto* member = ctx.dst->Member(kMemberName, member_ty,
- utils::Vector{
- ctx.dst->MemberSize(AInt(arr->Stride())),
- });
- ctx.dst->Structure(name, utils::Vector{member});
+ auto* member = b.Member(kMemberName, member_ty,
+ utils::Vector{
+ b.MemberSize(AInt(arr->Stride())),
+ });
+ b.Structure(name, utils::Vector{member});
return name;
});
auto* count = ctx.Clone(ast->count);
- return ctx.dst->ty.array(ctx.dst->ty.type_name(el_ty), count);
+ return b.ty.array(b.ty.type_name(el_ty), count);
}
if (ast::GetAttribute<ast::StrideAttribute>(ast->attributes)) {
// Strip the @stride attribute
auto* ty = ctx.Clone(ast->type);
auto* count = ctx.Clone(ast->count);
- return ctx.dst->ty.array(ty, count);
+ return b.ty.array(ty, count);
}
}
return nullptr;
@@ -96,11 +104,11 @@
// to insert an additional member accessor for the single structure field.
// Example: `arr[i]` -> `arr[i].el`
ctx.ReplaceAll([&](const ast::IndexAccessorExpression* idx) -> const ast::Expression* {
- if (auto* ty = ctx.src->TypeOf(idx->object)) {
+ if (auto* ty = src->TypeOf(idx->object)) {
if (auto* arr = ty->UnwrapRef()->As<sem::Array>()) {
if (!arr->IsStrideImplicit()) {
auto* expr = ctx.CloneWithoutTransform(idx);
- return ctx.dst->MemberAccessor(expr, kMemberName);
+ return b.MemberAccessor(expr, kMemberName);
}
}
}
@@ -136,21 +144,23 @@
if (auto it = decomposed.find(arr); it != decomposed.end()) {
args.Reserve(expr->args.Length());
for (auto* arg : expr->args) {
- args.Push(ctx.dst->Call(it->second, ctx.Clone(arg)));
+ args.Push(b.Call(it->second, ctx.Clone(arg)));
}
} else {
args = ctx.Clone(expr->args);
}
- return target.type ? ctx.dst->Construct(target.type, std::move(args))
- : ctx.dst->Call(target.name, std::move(args));
+ return target.type ? b.Construct(target.type, std::move(args))
+ : b.Call(target.name, std::move(args));
}
}
}
}
return nullptr;
});
+
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/decompose_strided_array.h b/src/tint/transform/decompose_strided_array.h
index 5dbaaa5..9555a9a 100644
--- a/src/tint/transform/decompose_strided_array.h
+++ b/src/tint/transform/decompose_strided_array.h
@@ -35,19 +35,10 @@
/// Destructor
~DecomposeStridedArray() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/decompose_strided_matrix.cc b/src/tint/transform/decompose_strided_matrix.cc
index 91aed43..5494ca2 100644
--- a/src/tint/transform/decompose_strided_matrix.cc
+++ b/src/tint/transform/decompose_strided_matrix.cc
@@ -53,24 +53,25 @@
};
};
-/// Return type of the callback function of GatherCustomStrideMatrixMembers
-enum GatherResult { kContinue, kStop };
+} // namespace
-/// GatherCustomStrideMatrixMembers scans `program` for all matrix members of
-/// storage and uniform structs, which are of a matrix type, and have a custom
-/// matrix stride attribute. For each matrix member found, `callback` is called.
-/// `callback` is a function with the signature:
-/// GatherResult(const sem::StructMember* member,
-/// sem::Matrix* matrix,
-/// uint32_t stride)
-/// If `callback` return GatherResult::kStop, then the scanning will immediately
-/// terminate, and GatherCustomStrideMatrixMembers() will return, otherwise
-/// scanning will continue.
-template <typename F>
-void GatherCustomStrideMatrixMembers(const Program* program, F&& callback) {
- for (auto* node : program->ASTNodes().Objects()) {
+DecomposeStridedMatrix::DecomposeStridedMatrix() = default;
+
+DecomposeStridedMatrix::~DecomposeStridedMatrix() = default;
+
+Transform::ApplyResult DecomposeStridedMatrix::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
+ // Scan the program for all storage and uniform structure matrix members with
+ // a custom stride attribute. Replace these matrices with an equivalent array,
+ // and populate the `decomposed` map with the members that have been replaced.
+ utils::Hashmap<const ast::StructMember*, MatrixInfo, 8> decomposed;
+ for (auto* node : src->ASTNodes().Objects()) {
if (auto* str = node->As<ast::Struct>()) {
- auto* str_ty = program->Sem().Get(str);
+ auto* str_ty = src->Sem().Get(str);
if (!str_ty->UsedAs(ast::AddressSpace::kUniform) &&
!str_ty->UsedAs(ast::AddressSpace::kStorage)) {
continue;
@@ -89,46 +90,20 @@
if (matrix->ColumnStride() == stride) {
continue;
}
- if (callback(member, matrix, stride) == GatherResult::kStop) {
- return;
- }
+ // We've got ourselves a struct member of a matrix type with a custom
+ // stride. Replace this with an array of column vectors.
+ MatrixInfo info{stride, matrix};
+ auto* replacement =
+ b.Member(member->Offset(), ctx.Clone(member->Name()), info.array(ctx.dst));
+ ctx.Replace(member->Declaration(), replacement);
+ decomposed.Add(member->Declaration(), info);
}
}
}
-}
-} // namespace
-
-DecomposeStridedMatrix::DecomposeStridedMatrix() = default;
-
-DecomposeStridedMatrix::~DecomposeStridedMatrix() = default;
-
-bool DecomposeStridedMatrix::ShouldRun(const Program* program, const DataMap&) const {
- bool should_run = false;
- GatherCustomStrideMatrixMembers(program,
- [&](const sem::StructMember*, const sem::Matrix*, uint32_t) {
- should_run = true;
- return GatherResult::kStop;
- });
- return should_run;
-}
-
-void DecomposeStridedMatrix::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- // Scan the program for all storage and uniform structure matrix members with
- // a custom stride attribute. Replace these matrices with an equivalent array,
- // and populate the `decomposed` map with the members that have been replaced.
- std::unordered_map<const ast::StructMember*, MatrixInfo> decomposed;
- GatherCustomStrideMatrixMembers(
- ctx.src, [&](const sem::StructMember* member, const sem::Matrix* matrix, uint32_t stride) {
- // We've got ourselves a struct member of a matrix type with a custom
- // stride. Replace this with an array of column vectors.
- MatrixInfo info{stride, matrix};
- auto* replacement =
- ctx.dst->Member(member->Offset(), ctx.Clone(member->Name()), info.array(ctx.dst));
- ctx.Replace(member->Declaration(), replacement);
- decomposed.emplace(member->Declaration(), info);
- return GatherResult::kContinue;
- });
+ if (decomposed.IsEmpty()) {
+ return SkipTransform;
+ }
// For all expressions where a single matrix column vector was indexed, we can
// preserve these without calling conversion functions.
@@ -136,12 +111,11 @@
// ssbo.mat[2] -> ssbo.mat[2]
ctx.ReplaceAll(
[&](const ast::IndexAccessorExpression* expr) -> const ast::IndexAccessorExpression* {
- if (auto* access = ctx.src->Sem().Get<sem::StructMemberAccess>(expr->object)) {
- auto it = decomposed.find(access->Member()->Declaration());
- if (it != decomposed.end()) {
+ if (auto* access = src->Sem().Get<sem::StructMemberAccess>(expr->object)) {
+ if (decomposed.Contains(access->Member()->Declaration())) {
auto* obj = ctx.CloneWithoutTransform(expr->object);
auto* idx = ctx.Clone(expr->index);
- return ctx.dst->IndexAccessor(obj, idx);
+ return b.IndexAccessor(obj, idx);
}
}
return nullptr;
@@ -154,39 +128,36 @@
// ssbo.mat = mat_to_arr(m)
std::unordered_map<MatrixInfo, Symbol, MatrixInfo::Hasher> mat_to_arr;
ctx.ReplaceAll([&](const ast::AssignmentStatement* stmt) -> const ast::Statement* {
- if (auto* access = ctx.src->Sem().Get<sem::StructMemberAccess>(stmt->lhs)) {
- auto it = decomposed.find(access->Member()->Declaration());
- if (it == decomposed.end()) {
- return nullptr;
+ if (auto* access = src->Sem().Get<sem::StructMemberAccess>(stmt->lhs)) {
+ if (auto* info = decomposed.Find(access->Member()->Declaration())) {
+ auto fn = utils::GetOrCreate(mat_to_arr, *info, [&] {
+ auto name =
+ b.Symbols().New("mat" + std::to_string(info->matrix->columns()) + "x" +
+ std::to_string(info->matrix->rows()) + "_stride_" +
+ std::to_string(info->stride) + "_to_arr");
+
+ auto matrix = [&] { return CreateASTTypeFor(ctx, info->matrix); };
+ auto array = [&] { return info->array(ctx.dst); };
+
+ auto mat = b.Sym("m");
+ utils::Vector<const ast::Expression*, 4> columns;
+ for (uint32_t i = 0; i < static_cast<uint32_t>(info->matrix->columns()); i++) {
+ columns.Push(b.IndexAccessor(mat, u32(i)));
+ }
+ b.Func(name,
+ utils::Vector{
+ b.Param(mat, matrix()),
+ },
+ array(),
+ utils::Vector{
+ b.Return(b.Construct(array(), columns)),
+ });
+ return name;
+ });
+ auto* lhs = ctx.CloneWithoutTransform(stmt->lhs);
+ auto* rhs = b.Call(fn, ctx.Clone(stmt->rhs));
+ return b.Assign(lhs, rhs);
}
- MatrixInfo info = it->second;
- auto fn = utils::GetOrCreate(mat_to_arr, info, [&] {
- auto name =
- ctx.dst->Symbols().New("mat" + std::to_string(info.matrix->columns()) + "x" +
- std::to_string(info.matrix->rows()) + "_stride_" +
- std::to_string(info.stride) + "_to_arr");
-
- auto matrix = [&] { return CreateASTTypeFor(ctx, info.matrix); };
- auto array = [&] { return info.array(ctx.dst); };
-
- auto mat = ctx.dst->Sym("m");
- utils::Vector<const ast::Expression*, 4> columns;
- for (uint32_t i = 0; i < static_cast<uint32_t>(info.matrix->columns()); i++) {
- columns.Push(ctx.dst->IndexAccessor(mat, u32(i)));
- }
- ctx.dst->Func(name,
- utils::Vector{
- ctx.dst->Param(mat, matrix()),
- },
- array(),
- utils::Vector{
- ctx.dst->Return(ctx.dst->Construct(array(), columns)),
- });
- return name;
- });
- auto* lhs = ctx.CloneWithoutTransform(stmt->lhs);
- auto* rhs = ctx.dst->Call(fn, ctx.Clone(stmt->rhs));
- return ctx.dst->Assign(lhs, rhs);
}
return nullptr;
});
@@ -196,41 +167,40 @@
// m = arr_to_mat(ssbo.mat)
std::unordered_map<MatrixInfo, Symbol, MatrixInfo::Hasher> arr_to_mat;
ctx.ReplaceAll([&](const ast::MemberAccessorExpression* expr) -> const ast::Expression* {
- if (auto* access = ctx.src->Sem().Get<sem::StructMemberAccess>(expr)) {
- auto it = decomposed.find(access->Member()->Declaration());
- if (it == decomposed.end()) {
- return nullptr;
+ if (auto* access = src->Sem().Get<sem::StructMemberAccess>(expr)) {
+ if (auto* info = decomposed.Find(access->Member()->Declaration())) {
+ auto fn = utils::GetOrCreate(arr_to_mat, *info, [&] {
+ auto name =
+ b.Symbols().New("arr_to_mat" + std::to_string(info->matrix->columns()) +
+ "x" + std::to_string(info->matrix->rows()) + "_stride_" +
+ std::to_string(info->stride));
+
+ auto matrix = [&] { return CreateASTTypeFor(ctx, info->matrix); };
+ auto array = [&] { return info->array(ctx.dst); };
+
+ auto arr = b.Sym("arr");
+ utils::Vector<const ast::Expression*, 4> columns;
+ for (uint32_t i = 0; i < static_cast<uint32_t>(info->matrix->columns()); i++) {
+ columns.Push(b.IndexAccessor(arr, u32(i)));
+ }
+ b.Func(name,
+ utils::Vector{
+ b.Param(arr, array()),
+ },
+ matrix(),
+ utils::Vector{
+ b.Return(b.Construct(matrix(), columns)),
+ });
+ return name;
+ });
+ return b.Call(fn, ctx.CloneWithoutTransform(expr));
}
- MatrixInfo info = it->second;
- auto fn = utils::GetOrCreate(arr_to_mat, info, [&] {
- auto name = ctx.dst->Symbols().New(
- "arr_to_mat" + std::to_string(info.matrix->columns()) + "x" +
- std::to_string(info.matrix->rows()) + "_stride_" + std::to_string(info.stride));
-
- auto matrix = [&] { return CreateASTTypeFor(ctx, info.matrix); };
- auto array = [&] { return info.array(ctx.dst); };
-
- auto arr = ctx.dst->Sym("arr");
- utils::Vector<const ast::Expression*, 4> columns;
- for (uint32_t i = 0; i < static_cast<uint32_t>(info.matrix->columns()); i++) {
- columns.Push(ctx.dst->IndexAccessor(arr, u32(i)));
- }
- ctx.dst->Func(name,
- utils::Vector{
- ctx.dst->Param(arr, array()),
- },
- matrix(),
- utils::Vector{
- ctx.dst->Return(ctx.dst->Construct(matrix(), columns)),
- });
- return name;
- });
- return ctx.dst->Call(fn, ctx.CloneWithoutTransform(expr));
}
return nullptr;
});
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/decompose_strided_matrix.h b/src/tint/transform/decompose_strided_matrix.h
index 40e9c3e..947dfc6 100644
--- a/src/tint/transform/decompose_strided_matrix.h
+++ b/src/tint/transform/decompose_strided_matrix.h
@@ -35,19 +35,10 @@
/// Destructor
~DecomposeStridedMatrix() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/disable_uniformity_analysis.cc b/src/tint/transform/disable_uniformity_analysis.cc
index 918b1f1..ffd0b18 100644
--- a/src/tint/transform/disable_uniformity_analysis.cc
+++ b/src/tint/transform/disable_uniformity_analysis.cc
@@ -27,14 +27,20 @@
DisableUniformityAnalysis::~DisableUniformityAnalysis() = default;
-bool DisableUniformityAnalysis::ShouldRun(const Program* program, const DataMap&) const {
- return !program->Sem().Module()->Extensions().Contains(
- ast::Extension::kChromiumDisableUniformityAnalysis);
-}
+Transform::ApplyResult DisableUniformityAnalysis::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (src->Sem().Module()->Extensions().Contains(
+ ast::Extension::kChromiumDisableUniformityAnalysis)) {
+ return SkipTransform;
+ }
-void DisableUniformityAnalysis::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- ctx.dst->Enable(ast::Extension::kChromiumDisableUniformityAnalysis);
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+ b.Enable(ast::Extension::kChromiumDisableUniformityAnalysis);
+
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/disable_uniformity_analysis.h b/src/tint/transform/disable_uniformity_analysis.h
index 3c9fb53..a9922af 100644
--- a/src/tint/transform/disable_uniformity_analysis.h
+++ b/src/tint/transform/disable_uniformity_analysis.h
@@ -27,19 +27,10 @@
/// Destructor
~DisableUniformityAnalysis() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/expand_compound_assignment.cc b/src/tint/transform/expand_compound_assignment.cc
index 85b9bf6..9fa81dd 100644
--- a/src/tint/transform/expand_compound_assignment.cc
+++ b/src/tint/transform/expand_compound_assignment.cc
@@ -31,11 +31,9 @@
namespace tint::transform {
-ExpandCompoundAssignment::ExpandCompoundAssignment() = default;
+namespace {
-ExpandCompoundAssignment::~ExpandCompoundAssignment() = default;
-
-bool ExpandCompoundAssignment::ShouldRun(const Program* program, const DataMap&) const {
+bool ShouldRun(const Program* program) {
for (auto* node : program->ASTNodes().Objects()) {
if (node->IsAnyOf<ast::CompoundAssignmentStatement, ast::IncrementDecrementStatement>()) {
return true;
@@ -44,21 +42,10 @@
return false;
}
-namespace {
+} // namespace
-/// Internal class used to collect statement expansions during the transform.
-class State {
- private:
- /// The clone context.
- CloneContext& ctx;
-
- /// The program builder.
- ProgramBuilder& b;
-
- /// The HoistToDeclBefore helper instance.
- HoistToDeclBefore hoist_to_decl_before;
-
- public:
+/// PIMPL state for the transform
+struct ExpandCompoundAssignment::State {
/// Constructor
/// @param context the clone context
explicit State(CloneContext& context) : ctx(context), b(*ctx.dst), hoist_to_decl_before(ctx) {}
@@ -158,18 +145,32 @@
ctx.Replace(stmt, b.Assign(new_lhs(), value));
}
- /// Finalize the transformation and clone the module.
- void Finalize() {
- hoist_to_decl_before.Apply();
- ctx.Clone();
- }
+ private:
+ /// The clone context.
+ CloneContext& ctx;
+
+ /// The program builder.
+ ProgramBuilder& b;
+
+ /// The HoistToDeclBefore helper instance.
+ HoistToDeclBefore hoist_to_decl_before;
};
-} // namespace
+ExpandCompoundAssignment::ExpandCompoundAssignment() = default;
-void ExpandCompoundAssignment::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+ExpandCompoundAssignment::~ExpandCompoundAssignment() = default;
+
+Transform::ApplyResult ExpandCompoundAssignment::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
+ }
+
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
State state(ctx);
- for (auto* node : ctx.src->ASTNodes().Objects()) {
+ for (auto* node : src->ASTNodes().Objects()) {
if (auto* assign = node->As<ast::CompoundAssignmentStatement>()) {
state.Expand(assign, assign->lhs, ctx.Clone(assign->rhs), assign->op);
} else if (auto* inc_dec = node->As<ast::IncrementDecrementStatement>()) {
@@ -178,7 +179,9 @@
state.Expand(inc_dec, inc_dec->lhs, ctx.dst->Expr(1_a), op);
}
}
- state.Finalize();
+
+ ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/expand_compound_assignment.h b/src/tint/transform/expand_compound_assignment.h
index 1081df7..6b299c5 100644
--- a/src/tint/transform/expand_compound_assignment.h
+++ b/src/tint/transform/expand_compound_assignment.h
@@ -45,19 +45,13 @@
/// Destructor
~ExpandCompoundAssignment() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ private:
+ struct State;
};
} // namespace tint::transform
diff --git a/src/tint/transform/first_index_offset.cc b/src/tint/transform/first_index_offset.cc
index cafca32..eb698be 100644
--- a/src/tint/transform/first_index_offset.cc
+++ b/src/tint/transform/first_index_offset.cc
@@ -35,6 +35,15 @@
constexpr char kFirstVertexName[] = "first_vertex_index";
constexpr char kFirstInstanceName[] = "first_instance_index";
+bool ShouldRun(const Program* program) {
+ for (auto* fn : program->AST().Functions()) {
+ if (fn->PipelineStage() == ast::PipelineStage::kVertex) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace
FirstIndexOffset::BindingPoint::BindingPoint() = default;
@@ -49,16 +58,16 @@
FirstIndexOffset::FirstIndexOffset() = default;
FirstIndexOffset::~FirstIndexOffset() = default;
-bool FirstIndexOffset::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* fn : program->AST().Functions()) {
- if (fn->PipelineStage() == ast::PipelineStage::kVertex) {
- return true;
- }
+Transform::ApplyResult FirstIndexOffset::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap& outputs) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
}
- return false;
-}
-void FirstIndexOffset::Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
// Get the uniform buffer binding point
uint32_t ub_binding = binding_;
uint32_t ub_group = group_;
@@ -115,17 +124,17 @@
if (has_vertex_or_instance_index) {
// Add uniform buffer members and calculate byte offsets
utils::Vector<const ast::StructMember*, 8> members;
- members.Push(ctx.dst->Member(kFirstVertexName, ctx.dst->ty.u32()));
- members.Push(ctx.dst->Member(kFirstInstanceName, ctx.dst->ty.u32()));
- auto* struct_ = ctx.dst->Structure(ctx.dst->Sym(), std::move(members));
+ members.Push(b.Member(kFirstVertexName, b.ty.u32()));
+ members.Push(b.Member(kFirstInstanceName, b.ty.u32()));
+ auto* struct_ = b.Structure(b.Sym(), std::move(members));
// Create a global to hold the uniform buffer
- Symbol buffer_name = ctx.dst->Sym();
- ctx.dst->GlobalVar(buffer_name, ctx.dst->ty.Of(struct_), ast::AddressSpace::kUniform,
- utils::Vector{
- ctx.dst->Binding(AInt(ub_binding)),
- ctx.dst->Group(AInt(ub_group)),
- });
+ Symbol buffer_name = b.Sym();
+ b.GlobalVar(buffer_name, b.ty.Of(struct_), ast::AddressSpace::kUniform,
+ utils::Vector{
+ b.Binding(AInt(ub_binding)),
+ b.Group(AInt(ub_group)),
+ });
// Fix up all references to the builtins with the offsets
ctx.ReplaceAll([=, &ctx](const ast::Expression* expr) -> const ast::Expression* {
@@ -150,9 +159,10 @@
});
}
- ctx.Clone();
-
outputs.Add<Data>(has_vertex_or_instance_index);
+
+ ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/first_index_offset.h b/src/tint/transform/first_index_offset.h
index 04758cd..f84d811 100644
--- a/src/tint/transform/first_index_offset.h
+++ b/src/tint/transform/first_index_offset.h
@@ -103,19 +103,10 @@
/// Destructor
~FirstIndexOffset() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
private:
uint32_t binding_ = 0;
diff --git a/src/tint/transform/for_loop_to_loop.cc b/src/tint/transform/for_loop_to_loop.cc
index e585790..63ccb12 100644
--- a/src/tint/transform/for_loop_to_loop.cc
+++ b/src/tint/transform/for_loop_to_loop.cc
@@ -14,17 +14,17 @@
#include "src/tint/transform/for_loop_to_loop.h"
+#include <utility>
+
#include "src/tint/ast/break_statement.h"
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::ForLoopToLoop);
namespace tint::transform {
-ForLoopToLoop::ForLoopToLoop() = default;
+namespace {
-ForLoopToLoop::~ForLoopToLoop() = default;
-
-bool ForLoopToLoop::ShouldRun(const Program* program, const DataMap&) const {
+bool ShouldRun(const Program* program) {
for (auto* node : program->ASTNodes().Objects()) {
if (node->Is<ast::ForLoopStatement>()) {
return true;
@@ -33,19 +33,31 @@
return false;
}
-void ForLoopToLoop::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+} // namespace
+
+ForLoopToLoop::ForLoopToLoop() = default;
+
+ForLoopToLoop::~ForLoopToLoop() = default;
+
+Transform::ApplyResult ForLoopToLoop::Apply(const Program* src, const DataMap&, DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
+ }
+
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
ctx.ReplaceAll([&](const ast::ForLoopStatement* for_loop) -> const ast::Statement* {
utils::Vector<const ast::Statement*, 8> stmts;
if (auto* cond = for_loop->condition) {
// !condition
- auto* not_cond =
- ctx.dst->create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, ctx.Clone(cond));
+ auto* not_cond = b.Not(ctx.Clone(cond));
// { break; }
- auto* break_body = ctx.dst->Block(ctx.dst->create<ast::BreakStatement>());
+ auto* break_body = b.Block(b.Break());
// if (!condition) { break; }
- stmts.Push(ctx.dst->If(not_cond, break_body));
+ stmts.Push(b.If(not_cond, break_body));
}
for (auto* stmt : for_loop->body->statements) {
stmts.Push(ctx.Clone(stmt));
@@ -53,20 +65,21 @@
const ast::BlockStatement* continuing = nullptr;
if (auto* cont = for_loop->continuing) {
- continuing = ctx.dst->Block(ctx.Clone(cont));
+ continuing = b.Block(ctx.Clone(cont));
}
- auto* body = ctx.dst->Block(stmts);
- auto* loop = ctx.dst->create<ast::LoopStatement>(body, continuing);
+ auto* body = b.Block(stmts);
+ auto* loop = b.Loop(body, continuing);
if (auto* init = for_loop->initializer) {
- return ctx.dst->Block(ctx.Clone(init), loop);
+ return b.Block(ctx.Clone(init), loop);
}
return loop;
});
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/for_loop_to_loop.h b/src/tint/transform/for_loop_to_loop.h
index 5ab690a..fe3db97 100644
--- a/src/tint/transform/for_loop_to_loop.h
+++ b/src/tint/transform/for_loop_to_loop.h
@@ -29,19 +29,10 @@
/// Destructor
~ForLoopToLoop() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/localize_struct_array_assignment.cc b/src/tint/transform/localize_struct_array_assignment.cc
index 8077393..bfe8865 100644
--- a/src/tint/transform/localize_struct_array_assignment.cc
+++ b/src/tint/transform/localize_struct_array_assignment.cc
@@ -32,70 +32,15 @@
namespace tint::transform {
-/// Private implementation of LocalizeStructArrayAssignment transform
-class LocalizeStructArrayAssignment::State {
- private:
- CloneContext& ctx;
- ProgramBuilder& b;
-
- /// Returns true if `expr` contains an index accessor expression to a
- /// structure member of array type.
- bool ContainsStructArrayIndex(const ast::Expression* expr) {
- bool result = false;
- ast::TraverseExpressions(
- expr, b.Diagnostics(), [&](const ast::IndexAccessorExpression* ia) {
- // Indexing using a runtime value?
- auto* idx_sem = ctx.src->Sem().Get(ia->index);
- if (!idx_sem->ConstantValue()) {
- // Indexing a member access expr?
- if (auto* ma = ia->object->As<ast::MemberAccessorExpression>()) {
- // That accesses an array?
- if (ctx.src->TypeOf(ma)->UnwrapRef()->Is<sem::Array>()) {
- result = true;
- return ast::TraverseAction::Stop;
- }
- }
- }
- return ast::TraverseAction::Descend;
- });
-
- return result;
- }
-
- // Returns the type and address space of the originating variable of the lhs
- // of the assignment statement.
- // See https://www.w3.org/TR/WGSL/#originating-variable-section
- std::pair<const sem::Type*, ast::AddressSpace> GetOriginatingTypeAndAddressSpace(
- const ast::AssignmentStatement* assign_stmt) {
- auto* source_var = ctx.src->Sem().Get(assign_stmt->lhs)->SourceVariable();
- if (!source_var) {
- TINT_ICE(Transform, b.Diagnostics())
- << "Unable to determine originating variable for lhs of assignment "
- "statement";
- return {};
- }
-
- auto* type = source_var->Type();
- if (auto* ref = type->As<sem::Reference>()) {
- return {ref->StoreType(), ref->AddressSpace()};
- } else if (auto* ptr = type->As<sem::Pointer>()) {
- return {ptr->StoreType(), ptr->AddressSpace()};
- }
-
- TINT_ICE(Transform, b.Diagnostics())
- << "Expecting to find variable of type pointer or reference on lhs "
- "of assignment statement";
- return {};
- }
-
- public:
+/// PIMPL state for the transform
+struct LocalizeStructArrayAssignment::State {
/// Constructor
- /// @param ctx_in the CloneContext primed with the input program and
- /// ProgramBuilder
- explicit State(CloneContext& ctx_in) : ctx(ctx_in), b(*ctx_in.dst) {}
+ /// @param program the source program
+ explicit State(const Program* program) : src(program) {}
/// Runs the transform
- void Run() {
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
struct Shared {
bool process_nested_nodes = false;
utils::Vector<const ast::Statement*, 4> insert_before_stmts;
@@ -189,6 +134,65 @@
});
ctx.Clone();
+ return Program(std::move(b));
+ }
+
+ private:
+ /// The source program
+ const Program* const src;
+ /// The target program builder
+ ProgramBuilder b;
+ /// The clone context
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
+
+ /// Returns true if `expr` contains an index accessor expression to a
+ /// structure member of array type.
+ bool ContainsStructArrayIndex(const ast::Expression* expr) {
+ bool result = false;
+ ast::TraverseExpressions(
+ expr, b.Diagnostics(), [&](const ast::IndexAccessorExpression* ia) {
+ // Indexing using a runtime value?
+ auto* idx_sem = src->Sem().Get(ia->index);
+ if (!idx_sem->ConstantValue()) {
+ // Indexing a member access expr?
+ if (auto* ma = ia->object->As<ast::MemberAccessorExpression>()) {
+ // That accesses an array?
+ if (src->TypeOf(ma)->UnwrapRef()->Is<sem::Array>()) {
+ result = true;
+ return ast::TraverseAction::Stop;
+ }
+ }
+ }
+ return ast::TraverseAction::Descend;
+ });
+
+ return result;
+ }
+
+ // Returns the type and address space of the originating variable of the lhs
+ // of the assignment statement.
+ // See https://www.w3.org/TR/WGSL/#originating-variable-section
+ std::pair<const sem::Type*, ast::AddressSpace> GetOriginatingTypeAndAddressSpace(
+ const ast::AssignmentStatement* assign_stmt) {
+ auto* source_var = src->Sem().Get(assign_stmt->lhs)->SourceVariable();
+ if (!source_var) {
+ TINT_ICE(Transform, b.Diagnostics())
+ << "Unable to determine originating variable for lhs of assignment "
+ "statement";
+ return {};
+ }
+
+ auto* type = source_var->Type();
+ if (auto* ref = type->As<sem::Reference>()) {
+ return {ref->StoreType(), ref->AddressSpace()};
+ } else if (auto* ptr = type->As<sem::Pointer>()) {
+ return {ptr->StoreType(), ptr->AddressSpace()};
+ }
+
+ TINT_ICE(Transform, b.Diagnostics())
+ << "Expecting to find variable of type pointer or reference on lhs "
+ "of assignment statement";
+ return {};
}
};
@@ -196,9 +200,10 @@
LocalizeStructArrayAssignment::~LocalizeStructArrayAssignment() = default;
-void LocalizeStructArrayAssignment::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- State state(ctx);
- state.Run();
+Transform::ApplyResult LocalizeStructArrayAssignment::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ return State{src}.Run();
}
} // namespace tint::transform
diff --git a/src/tint/transform/localize_struct_array_assignment.h b/src/tint/transform/localize_struct_array_assignment.h
index 130f8cc..169e33c 100644
--- a/src/tint/transform/localize_struct_array_assignment.h
+++ b/src/tint/transform/localize_struct_array_assignment.h
@@ -36,17 +36,13 @@
/// Destructor
~LocalizeStructArrayAssignment() override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
private:
- class State;
+ struct State;
};
} // namespace tint::transform
diff --git a/src/tint/transform/manager.cc b/src/tint/transform/manager.cc
index 4e83320..79603c8 100644
--- a/src/tint/transform/manager.cc
+++ b/src/tint/transform/manager.cc
@@ -31,9 +31,9 @@
Manager::Manager() = default;
Manager::~Manager() = default;
-Output Manager::Run(const Program* program, const DataMap& data) const {
- const Program* in = program;
-
+Transform::ApplyResult Manager::Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const {
#if TINT_PRINT_PROGRAM_FOR_EACH_TRANSFORM
auto print_program = [&](const char* msg, const Transform* transform) {
auto wgsl = Program::printer(in);
@@ -46,34 +46,30 @@
};
#endif
- Output out;
+ std::optional<Program> output;
+
for (const auto& transform : transforms_) {
- if (!transform->ShouldRun(in, data)) {
- TINT_IF_PRINT_PROGRAM(std::cout << "Skipping " << transform->TypeInfo().name
- << std::endl);
- continue;
- }
TINT_IF_PRINT_PROGRAM(print_program("Input to", transform.get()));
- auto res = transform->Run(in, data);
- out.program = std::move(res.program);
- out.data.Add(std::move(res.data));
- in = &out.program;
- if (!in->IsValid()) {
- TINT_IF_PRINT_PROGRAM(print_program("Invalid output of", transform.get()));
- return out;
- }
+ if (auto result = transform->Apply(program, inputs, outputs)) {
+ output.emplace(std::move(result.value()));
+ program = &output.value();
- if (transform == transforms_.back()) {
- TINT_IF_PRINT_PROGRAM(print_program("Output of", transform.get()));
+ if (!program->IsValid()) {
+ TINT_IF_PRINT_PROGRAM(print_program("Invalid output of", transform.get()));
+ break;
+ }
+
+ if (transform == transforms_.back()) {
+ TINT_IF_PRINT_PROGRAM(print_program("Output of", transform.get()));
+ }
+ } else {
+ TINT_IF_PRINT_PROGRAM(std::cout << "Skipped " << transform->TypeInfo().name
+ << std::endl);
}
}
- if (program == in) {
- out.program = program->Clone();
- }
-
- return out;
+ return output;
}
} // namespace tint::transform
diff --git a/src/tint/transform/manager.h b/src/tint/transform/manager.h
index 9d4049f..64ca847 100644
--- a/src/tint/transform/manager.h
+++ b/src/tint/transform/manager.h
@@ -47,11 +47,10 @@
transforms_.emplace_back(std::make_unique<T>(std::forward<ARGS>(args)...));
}
- /// Runs the transforms on `program`, returning the transformation result.
- /// @param program the source program to transform
- /// @param data optional extra transform-specific input data
- /// @returns the transformed program and diagnostics
- Output Run(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
private:
std::vector<std::unique_ptr<Transform>> transforms_;
diff --git a/src/tint/transform/merge_return.cc b/src/tint/transform/merge_return.cc
index aec6b6d..2b45b73 100644
--- a/src/tint/transform/merge_return.cc
+++ b/src/tint/transform/merge_return.cc
@@ -65,15 +65,6 @@
MergeReturn::~MergeReturn() = default;
-bool MergeReturn::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* func : program->AST().Functions()) {
- if (NeedsTransform(program, func)) {
- return true;
- }
- }
- return false;
-}
-
namespace {
/// Internal class used to during the transform.
@@ -223,7 +214,12 @@
} // namespace
-void MergeReturn::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+Transform::ApplyResult MergeReturn::Apply(const Program* src, const DataMap&, DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
+ bool made_changes = false;
+
for (auto* func : ctx.src->AST().Functions()) {
if (!NeedsTransform(ctx.src, func)) {
continue;
@@ -231,9 +227,15 @@
State state(ctx, func);
state.ProcessStatement(func->body);
+ made_changes = true;
+ }
+
+ if (!made_changes) {
+ return SkipTransform;
}
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/merge_return.h b/src/tint/transform/merge_return.h
index 1334a5c..f6db5c2 100644
--- a/src/tint/transform/merge_return.h
+++ b/src/tint/transform/merge_return.h
@@ -27,19 +27,10 @@
/// Destructor
~MergeReturn() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param.cc b/src/tint/transform/module_scope_var_to_entry_point_param.cc
index f9c11e5..16a622e 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param.cc
+++ b/src/tint/transform/module_scope_var_to_entry_point_param.cc
@@ -38,6 +38,15 @@
// The name of the struct member for arrays that are wrapped in structures.
const char* kWrappedArrayMemberName = "arr";
+bool ShouldRun(const Program* program) {
+ for (auto* decl : program->AST().GlobalDeclarations()) {
+ if (decl->Is<ast::Variable>()) {
+ return true;
+ }
+ }
+ return false;
+}
+
// Returns `true` if `type` is or contains a matrix type.
bool ContainsMatrix(const sem::Type* type) {
type = type->UnwrapRef();
@@ -56,7 +65,7 @@
}
} // namespace
-/// State holds the current transform state.
+/// PIMPL state for the transform
struct ModuleScopeVarToEntryPointParam::State {
/// The clone context.
CloneContext& ctx;
@@ -501,19 +510,20 @@
ModuleScopeVarToEntryPointParam::~ModuleScopeVarToEntryPointParam() = default;
-bool ModuleScopeVarToEntryPointParam::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* decl : program->AST().GlobalDeclarations()) {
- if (decl->Is<ast::Variable>()) {
- return true;
- }
+Transform::ApplyResult ModuleScopeVarToEntryPointParam::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
}
- return false;
-}
-void ModuleScopeVarToEntryPointParam::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
State state{ctx};
state.Process();
+
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param.h b/src/tint/transform/module_scope_var_to_entry_point_param.h
index 75bdaf3..377151f 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param.h
+++ b/src/tint/transform/module_scope_var_to_entry_point_param.h
@@ -69,20 +69,12 @@
/// Destructor
~ModuleScopeVarToEntryPointParam() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
-
+ private:
struct State;
};
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index 002b858..c3ebf4a 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -31,6 +31,17 @@
namespace tint::transform {
namespace {
+bool ShouldRun(const Program* program) {
+ for (auto* node : program->ASTNodes().Objects()) {
+ if (auto* ty = node->As<ast::Type>()) {
+ if (program->Sem().Get<sem::ExternalTexture>(ty)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/// This struct stores symbols for new bindings created as a result of transforming a
/// texture_external instance.
struct NewBindingSymbols {
@@ -40,7 +51,7 @@
};
} // namespace
-/// State holds the current transform state
+/// PIMPL state for the transform
struct MultiplanarExternalTexture::State {
/// The clone context.
CloneContext& ctx;
@@ -537,30 +548,26 @@
MultiplanarExternalTexture::MultiplanarExternalTexture() = default;
MultiplanarExternalTexture::~MultiplanarExternalTexture() = default;
-bool MultiplanarExternalTexture::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* node : program->ASTNodes().Objects()) {
- if (auto* ty = node->As<ast::Type>()) {
- if (program->Sem().Get<sem::ExternalTexture>(ty)) {
- return true;
- }
- }
- }
- return false;
-}
-
// Within this transform, an instance of a texture_external binding is unpacked into two
// texture_2d<f32> bindings representing two possible planes of a single texture and a uniform
// buffer binding representing a struct of parameters. Calls to texture builtins that contain a
// texture_external parameter will be transformed into a newly generated version of the function,
// which can perform the desired operation on a single RGBA plane or on separate Y and UV planes.
-void MultiplanarExternalTexture::Run(CloneContext& ctx, const DataMap& inputs, DataMap&) const {
+Transform::ApplyResult MultiplanarExternalTexture::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap&) const {
auto* new_binding_points = inputs.Get<NewBindingPoints>();
+ if (!ShouldRun(src)) {
+ return SkipTransform;
+ }
+
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
if (!new_binding_points) {
- ctx.dst->Diagnostics().add_error(
- diag::System::Transform,
- "missing new binding point data for " + std::string(TypeInfo().name));
- return;
+ b.Diagnostics().add_error(diag::System::Transform, "missing new binding point data for " +
+ std::string(TypeInfo().name));
+ return Program(std::move(b));
}
State state(ctx, new_binding_points);
@@ -568,6 +575,7 @@
state.Process();
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/multiplanar_external_texture.h b/src/tint/transform/multiplanar_external_texture.h
index a10fed4..695e38c 100644
--- a/src/tint/transform/multiplanar_external_texture.h
+++ b/src/tint/transform/multiplanar_external_texture.h
@@ -80,21 +80,13 @@
/// Destructor
~MultiplanarExternalTexture() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- protected:
+ private:
struct State;
-
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/multiplanar_external_texture_test.cc b/src/tint/transform/multiplanar_external_texture_test.cc
index dacbb1e..4416d35 100644
--- a/src/tint/transform/multiplanar_external_texture_test.cc
+++ b/src/tint/transform/multiplanar_external_texture_test.cc
@@ -23,7 +23,11 @@
TEST_F(MultiplanarExternalTextureTest, ShouldRunEmptyModule) {
auto* src = R"()";
- EXPECT_FALSE(ShouldRun<MultiplanarExternalTexture>(src));
+ DataMap data;
+ data.Add<MultiplanarExternalTexture::NewBindingPoints>(
+ MultiplanarExternalTexture::BindingsMap{{{0, 0}, {{0, 1}, {0, 2}}}});
+
+ EXPECT_FALSE(ShouldRun<MultiplanarExternalTexture>(src, data));
}
TEST_F(MultiplanarExternalTextureTest, ShouldRunHasExternalTextureAlias) {
@@ -31,14 +35,22 @@
type ET = texture_external;
)";
- EXPECT_TRUE(ShouldRun<MultiplanarExternalTexture>(src));
+ DataMap data;
+ data.Add<MultiplanarExternalTexture::NewBindingPoints>(
+ MultiplanarExternalTexture::BindingsMap{{{0, 0}, {{0, 1}, {0, 2}}}});
+
+ EXPECT_TRUE(ShouldRun<MultiplanarExternalTexture>(src, data));
}
TEST_F(MultiplanarExternalTextureTest, ShouldRunHasExternalTextureGlobal) {
auto* src = R"(
@group(0) @binding(0) var ext_tex : texture_external;
)";
- EXPECT_TRUE(ShouldRun<MultiplanarExternalTexture>(src));
+ DataMap data;
+ data.Add<MultiplanarExternalTexture::NewBindingPoints>(
+ MultiplanarExternalTexture::BindingsMap{{{0, 0}, {{0, 1}, {0, 2}}}});
+
+ EXPECT_TRUE(ShouldRun<MultiplanarExternalTexture>(src, data));
}
TEST_F(MultiplanarExternalTextureTest, ShouldRunHasExternalTextureParam) {
@@ -46,7 +58,11 @@
fn f(ext_tex : texture_external) {}
)";
- EXPECT_TRUE(ShouldRun<MultiplanarExternalTexture>(src));
+ DataMap data;
+ data.Add<MultiplanarExternalTexture::NewBindingPoints>(
+ MultiplanarExternalTexture::BindingsMap{{{0, 0}, {{0, 1}, {0, 2}}}});
+
+ EXPECT_TRUE(ShouldRun<MultiplanarExternalTexture>(src, data));
}
// Running the transform without passing in data for the new bindings should result in an error.
diff --git a/src/tint/transform/num_workgroups_from_uniform.cc b/src/tint/transform/num_workgroups_from_uniform.cc
index 2122f07..e6681ca 100644
--- a/src/tint/transform/num_workgroups_from_uniform.cc
+++ b/src/tint/transform/num_workgroups_from_uniform.cc
@@ -29,6 +29,18 @@
namespace tint::transform {
namespace {
+
+bool ShouldRun(const Program* program) {
+ for (auto* node : program->ASTNodes().Objects()) {
+ if (auto* attr = node->As<ast::BuiltinAttribute>()) {
+ if (attr->builtin == ast::BuiltinValue::kNumWorkgroups) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/// Accessor describes the identifiers used in a member accessor that is being
/// used to retrieve the num_workgroups builtin from a parameter.
struct Accessor {
@@ -44,41 +56,40 @@
size_t operator()(const Accessor& a) const { return utils::Hash(a.param, a.member); }
};
};
+
} // namespace
NumWorkgroupsFromUniform::NumWorkgroupsFromUniform() = default;
NumWorkgroupsFromUniform::~NumWorkgroupsFromUniform() = default;
-bool NumWorkgroupsFromUniform::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* node : program->ASTNodes().Objects()) {
- if (auto* attr = node->As<ast::BuiltinAttribute>()) {
- if (attr->builtin == ast::BuiltinValue::kNumWorkgroups) {
- return true;
- }
- }
- }
- return false;
-}
+Transform::ApplyResult NumWorkgroupsFromUniform::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
-void NumWorkgroupsFromUniform::Run(CloneContext& ctx, const DataMap& inputs, DataMap&) const {
auto* cfg = inputs.Get<Config>();
if (cfg == nullptr) {
- ctx.dst->Diagnostics().add_error(
- diag::System::Transform, "missing transform data for " + std::string(TypeInfo().name));
- return;
+ b.Diagnostics().add_error(diag::System::Transform,
+ "missing transform data for " + std::string(TypeInfo().name));
+ return Program(std::move(b));
+ }
+
+ if (!ShouldRun(src)) {
+ return SkipTransform;
}
const char* kNumWorkgroupsMemberName = "num_workgroups";
// Find all entry point parameters that declare the num_workgroups builtin.
std::unordered_set<Accessor, Accessor::Hasher> to_replace;
- for (auto* func : ctx.src->AST().Functions()) {
+ for (auto* func : src->AST().Functions()) {
// num_workgroups is only valid for compute stages.
if (func->PipelineStage() != ast::PipelineStage::kCompute) {
continue;
}
- for (auto* param : ctx.src->Sem().Get(func)->Parameters()) {
+ for (auto* param : src->Sem().Get(func)->Parameters()) {
// Because the CanonicalizeEntryPointIO transform has been run, builtins
// will only appear as struct members.
auto* str = param->Type()->As<sem::Struct>();
@@ -108,7 +119,7 @@
// If this is the only member, remove the struct and parameter too.
if (str->Members().size() == 1) {
ctx.Remove(func->params, param->Declaration());
- ctx.Remove(ctx.src->AST().GlobalDeclarations(), str->Declaration());
+ ctx.Remove(src->AST().GlobalDeclarations(), str->Declaration());
}
}
}
@@ -119,11 +130,10 @@
const ast::Variable* num_workgroups_ubo = nullptr;
auto get_ubo = [&]() {
if (!num_workgroups_ubo) {
- auto* num_workgroups_struct = ctx.dst->Structure(
- ctx.dst->Sym(),
- utils::Vector{
- ctx.dst->Member(kNumWorkgroupsMemberName, ctx.dst->ty.vec3(ctx.dst->ty.u32())),
- });
+ auto* num_workgroups_struct =
+ b.Structure(b.Sym(), utils::Vector{
+ b.Member(kNumWorkgroupsMemberName, b.ty.vec3(b.ty.u32())),
+ });
uint32_t group, binding;
if (cfg->ubo_binding.has_value()) {
@@ -135,9 +145,9 @@
// plus 1, or group 0 if no resource bound.
group = 0;
- for (auto* global : ctx.src->AST().GlobalVariables()) {
+ for (auto* global : src->AST().GlobalVariables()) {
if (global->HasBindingPoint()) {
- auto* global_sem = ctx.src->Sem().Get<sem::GlobalVariable>(global);
+ auto* global_sem = src->Sem().Get<sem::GlobalVariable>(global);
auto binding_point = global_sem->BindingPoint();
if (binding_point.group >= group) {
group = binding_point.group + 1;
@@ -148,16 +158,16 @@
binding = 0;
}
- num_workgroups_ubo = ctx.dst->GlobalVar(
- ctx.dst->Sym(), ctx.dst->ty.Of(num_workgroups_struct), ast::AddressSpace::kUniform,
- ctx.dst->Group(AInt(group)), ctx.dst->Binding(AInt(binding)));
+ num_workgroups_ubo =
+ b.GlobalVar(b.Sym(), b.ty.Of(num_workgroups_struct), ast::AddressSpace::kUniform,
+ b.Group(AInt(group)), b.Binding(AInt(binding)));
}
return num_workgroups_ubo;
};
// Now replace all the places where the builtins are accessed with the value
// loaded from the uniform buffer.
- for (auto* node : ctx.src->ASTNodes().Objects()) {
+ for (auto* node : src->ASTNodes().Objects()) {
auto* accessor = node->As<ast::MemberAccessorExpression>();
if (!accessor) {
continue;
@@ -168,12 +178,12 @@
}
if (to_replace.count({ident->symbol, accessor->member->symbol})) {
- ctx.Replace(accessor,
- ctx.dst->MemberAccessor(get_ubo()->symbol, kNumWorkgroupsMemberName));
+ ctx.Replace(accessor, b.MemberAccessor(get_ubo()->symbol, kNumWorkgroupsMemberName));
}
}
ctx.Clone();
+ return Program(std::move(b));
}
NumWorkgroupsFromUniform::Config::Config(std::optional<sem::BindingPoint> ubo_bp)
diff --git a/src/tint/transform/num_workgroups_from_uniform.h b/src/tint/transform/num_workgroups_from_uniform.h
index 292c823..25308f2 100644
--- a/src/tint/transform/num_workgroups_from_uniform.h
+++ b/src/tint/transform/num_workgroups_from_uniform.h
@@ -72,19 +72,10 @@
std::optional<sem::BindingPoint> ubo_binding;
};
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/num_workgroups_from_uniform_test.cc b/src/tint/transform/num_workgroups_from_uniform_test.cc
index 093081c..435ab33 100644
--- a/src/tint/transform/num_workgroups_from_uniform_test.cc
+++ b/src/tint/transform/num_workgroups_from_uniform_test.cc
@@ -28,7 +28,9 @@
TEST_F(NumWorkgroupsFromUniformTest, ShouldRunEmptyModule) {
auto* src = R"()";
- EXPECT_FALSE(ShouldRun<NumWorkgroupsFromUniform>(src));
+ DataMap data;
+ data.Add<NumWorkgroupsFromUniform::Config>(sem::BindingPoint{0, 30u});
+ EXPECT_FALSE(ShouldRun<NumWorkgroupsFromUniform>(src, data));
}
TEST_F(NumWorkgroupsFromUniformTest, ShouldRunHasNumWorkgroups) {
@@ -38,7 +40,9 @@
}
)";
- EXPECT_TRUE(ShouldRun<NumWorkgroupsFromUniform>(src));
+ DataMap data;
+ data.Add<NumWorkgroupsFromUniform::Config>(sem::BindingPoint{0, 30u});
+ EXPECT_TRUE(ShouldRun<NumWorkgroupsFromUniform>(src, data));
}
TEST_F(NumWorkgroupsFromUniformTest, Error_MissingTransformData) {
@@ -55,7 +59,6 @@
DataMap data;
data.Add<CanonicalizeEntryPointIO::Config>(CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
auto got = Run<Unshadow, CanonicalizeEntryPointIO, NumWorkgroupsFromUniform>(src, data);
-
EXPECT_EQ(expect, str(got));
}
diff --git a/src/tint/transform/packed_vec3.cc b/src/tint/transform/packed_vec3.cc
index dde5aca..e947a53 100644
--- a/src/tint/transform/packed_vec3.cc
+++ b/src/tint/transform/packed_vec3.cc
@@ -33,14 +33,15 @@
namespace tint::transform {
-/// The PIMPL state for the PackedVec3 transform
+/// PIMPL state for the transform
struct PackedVec3::State {
/// Constructor
- /// @param c the CloneContext
- explicit State(CloneContext& c) : ctx(c) {}
+ /// @param program the source program
+ explicit State(const Program* program) : src(program) {}
/// Runs the transform
- void Run() {
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
// Packed vec3<T> struct members
utils::Hashset<const sem::StructMember*, 8> members;
@@ -72,6 +73,10 @@
}
}
+ if (members.IsEmpty()) {
+ return SkipTransform;
+ }
+
// Walk the nodes, starting with the most deeply nested, finding all the AST expressions
// that load a whole packed vector (not a scalar / swizzle of the vector).
utils::Hashset<const sem::Expression*, 16> refs;
@@ -137,36 +142,20 @@
}
ctx.Clone();
- }
-
- /// @returns true if this transform should be run for the given program
- /// @param program the program to inspect
- static bool ShouldRun(const Program* program) {
- for (auto* decl : program->AST().GlobalDeclarations()) {
- if (auto* str = program->Sem().Get<sem::Struct>(decl)) {
- if (str->IsHostShareable()) {
- for (auto* member : str->Members()) {
- if (auto* vec = member->Type()->As<sem::Vector>()) {
- if (vec->Width() == 3) {
- return true;
- }
- }
- }
- }
- }
- }
- return false;
+ return Program(std::move(b));
}
private:
+ /// The source program
+ const Program* const src;
+ /// The target program builder
+ ProgramBuilder b;
/// The clone context
- CloneContext& ctx;
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
/// Alias to the semantic info in ctx.src
const sem::Info& sem = ctx.src->Sem();
/// Alias to the symbols in ctx.src
const SymbolTable& sym = ctx.src->Symbols();
- /// Alias to the ctx.dst program builder
- ProgramBuilder& b = *ctx.dst;
};
PackedVec3::Attribute::Attribute(ProgramID pid, ast::NodeID nid) : Base(pid, nid) {}
@@ -183,12 +172,8 @@
PackedVec3::PackedVec3() = default;
PackedVec3::~PackedVec3() = default;
-bool PackedVec3::ShouldRun(const Program* program, const DataMap&) const {
- return State::ShouldRun(program);
-}
-
-void PackedVec3::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- State(ctx).Run();
+Transform::ApplyResult PackedVec3::Apply(const Program* src, const DataMap&, DataMap&) const {
+ return State{src}.Run();
}
} // namespace tint::transform
diff --git a/src/tint/transform/packed_vec3.h b/src/tint/transform/packed_vec3.h
index 9d899cb..0d304fa 100644
--- a/src/tint/transform/packed_vec3.h
+++ b/src/tint/transform/packed_vec3.h
@@ -56,21 +56,13 @@
/// Destructor
~PackedVec3() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
private:
struct State;
-
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/pad_structs.cc b/src/tint/transform/pad_structs.cc
index 10b0565..4ceb39d 100644
--- a/src/tint/transform/pad_structs.cc
+++ b/src/tint/transform/pad_structs.cc
@@ -50,8 +50,10 @@
PadStructs::~PadStructs() = default;
-void PadStructs::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- auto& sem = ctx.src->Sem();
+Transform::ApplyResult PadStructs::Apply(const Program* src, const DataMap&, DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+ auto& sem = src->Sem();
std::unordered_map<const ast::Struct*, const ast::Struct*> replaced_structs;
utils::Hashset<const ast::StructMember*, 8> padding_members;
@@ -65,7 +67,7 @@
bool has_runtime_sized_array = false;
utils::Vector<const ast::StructMember*, 8> new_members;
for (auto* mem : str->Members()) {
- auto name = ctx.src->Symbols().NameFor(mem->Name());
+ auto name = src->Symbols().NameFor(mem->Name());
if (offset < mem->Offset()) {
CreatePadding(&new_members, &padding_members, ctx.dst, mem->Offset() - offset);
@@ -75,7 +77,7 @@
auto* ty = mem->Type();
const ast::Type* type = CreateASTTypeFor(ctx, ty);
- new_members.Push(ctx.dst->Member(name, type));
+ new_members.Push(b.Member(name, type));
uint32_t size = ty->Size();
if (ty->Is<sem::Struct>() && str->UsedAs(ast::AddressSpace::kUniform)) {
@@ -97,8 +99,8 @@
if (offset < struct_size && !has_runtime_sized_array) {
CreatePadding(&new_members, &padding_members, ctx.dst, struct_size - offset);
}
- auto* new_struct = ctx.dst->create<ast::Struct>(ctx.Clone(ast_str->name),
- std::move(new_members), utils::Empty);
+ auto* new_struct =
+ b.create<ast::Struct>(ctx.Clone(ast_str->name), std::move(new_members), utils::Empty);
replaced_structs[ast_str] = new_struct;
return new_struct;
});
@@ -131,16 +133,17 @@
auto* arg = ast_call->args.begin();
for (auto* member : new_struct->members) {
if (padding_members.Contains(member)) {
- new_args.Push(ctx.dst->Expr(0_u));
+ new_args.Push(b.Expr(0_u));
} else {
new_args.Push(ctx.Clone(*arg));
arg++;
}
}
- return ctx.dst->Construct(CreateASTTypeFor(ctx, str), new_args);
+ return b.Construct(CreateASTTypeFor(ctx, str), new_args);
});
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/pad_structs.h b/src/tint/transform/pad_structs.h
index 55fec74..e9996d4 100644
--- a/src/tint/transform/pad_structs.h
+++ b/src/tint/transform/pad_structs.h
@@ -30,14 +30,10 @@
/// Destructor
~PadStructs() override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/promote_initializers_to_let.cc b/src/tint/transform/promote_initializers_to_let.cc
index 22cdc20..9e02c45 100644
--- a/src/tint/transform/promote_initializers_to_let.cc
+++ b/src/tint/transform/promote_initializers_to_let.cc
@@ -13,6 +13,9 @@
// limitations under the License.
#include "src/tint/transform/promote_initializers_to_let.h"
+
+#include <utility>
+
#include "src/tint/program_builder.h"
#include "src/tint/sem/call.h"
#include "src/tint/sem/statement.h"
@@ -27,9 +30,16 @@
PromoteInitializersToLet::~PromoteInitializersToLet() = default;
-void PromoteInitializersToLet::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+Transform::ApplyResult PromoteInitializersToLet::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
HoistToDeclBefore hoist_to_decl_before(ctx);
+ bool any_promoted = false;
+
// Hoists array and structure initializers to a constant variable, declared
// just before the statement of usage.
auto promote = [&](const sem::Expression* expr) {
@@ -59,14 +69,15 @@
return true;
}
+ any_promoted = true;
return hoist_to_decl_before.Add(expr, expr->Declaration(), true);
};
- for (auto* node : ctx.src->ASTNodes().Objects()) {
+ for (auto* node : src->ASTNodes().Objects()) {
bool ok = Switch(
node, //
[&](const ast::CallExpression* expr) {
- if (auto* sem = ctx.src->Sem().Get(expr)) {
+ if (auto* sem = src->Sem().Get(expr)) {
auto* ctor = sem->UnwrapMaterialize()->As<sem::Call>();
if (ctor->Target()->Is<sem::TypeInitializer>()) {
return promote(sem);
@@ -75,7 +86,7 @@
return true;
},
[&](const ast::IdentifierExpression* expr) {
- if (auto* sem = ctx.src->Sem().Get(expr)) {
+ if (auto* sem = src->Sem().Get(expr)) {
if (auto* user = sem->UnwrapMaterialize()->As<sem::VariableUser>()) {
// Identifier resolves to a variable
if (auto* stmt = user->Stmt()) {
@@ -96,14 +107,17 @@
return true;
},
[&](Default) { return true; });
-
if (!ok) {
- return;
+ return Program(std::move(b));
}
}
- hoist_to_decl_before.Apply();
+ if (!any_promoted) {
+ return SkipTransform;
+ }
+
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/promote_initializers_to_let.h b/src/tint/transform/promote_initializers_to_let.h
index 78793c7..b1bb291 100644
--- a/src/tint/transform/promote_initializers_to_let.h
+++ b/src/tint/transform/promote_initializers_to_let.h
@@ -33,14 +33,10 @@
/// Destructor
~PromoteInitializersToLet() override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/promote_side_effects_to_decl.cc b/src/tint/transform/promote_side_effects_to_decl.cc
index e36c416..ea13b0b 100644
--- a/src/tint/transform/promote_side_effects_to_decl.cc
+++ b/src/tint/transform/promote_side_effects_to_decl.cc
@@ -53,36 +53,36 @@
// to else {if}s so that the next transform, DecomposeSideEffects, can insert
// hoisted expressions above their current location.
struct SimplifySideEffectStatements : Castable<PromoteSideEffectsToDecl, Transform> {
- class State;
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap&) const override;
+ ApplyResult Apply(const Program* src, const DataMap& inputs, DataMap& outputs) const override;
};
-class SimplifySideEffectStatements::State : public StateBase {
- HoistToDeclBefore hoist_to_decl_before;
+Transform::ApplyResult SimplifySideEffectStatements::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
- public:
- explicit State(CloneContext& ctx_in) : StateBase(ctx_in), hoist_to_decl_before(ctx_in) {}
+ bool made_changes = false;
- void Run() {
- for (auto* node : ctx.src->ASTNodes().Objects()) {
- if (auto* expr = node->As<ast::Expression>()) {
- auto* sem_expr = sem.Get(expr);
- if (!sem_expr || !sem_expr->HasSideEffects()) {
- continue;
- }
-
- hoist_to_decl_before.Prepare(sem_expr);
+ HoistToDeclBefore hoist_to_decl_before(ctx);
+ for (auto* node : ctx.src->ASTNodes().Objects()) {
+ if (auto* expr = node->As<ast::Expression>()) {
+ auto* sem_expr = src->Sem().Get(expr);
+ if (!sem_expr || !sem_expr->HasSideEffects()) {
+ continue;
}
+
+ hoist_to_decl_before.Prepare(sem_expr);
+ made_changes = true;
}
-
- hoist_to_decl_before.Apply();
- ctx.Clone();
}
-};
-void SimplifySideEffectStatements::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- State state(ctx);
- state.Run();
+ if (!made_changes) {
+ return SkipTransform;
+ }
+
+ ctx.Clone();
+ return Program(std::move(b));
}
// Decomposes side-effecting expressions to ensure order of evaluation. This
@@ -91,7 +91,7 @@
struct DecomposeSideEffects : Castable<PromoteSideEffectsToDecl, Transform> {
class CollectHoistsState;
class DecomposeState;
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap&) const override;
+ ApplyResult Apply(const Program* src, const DataMap& inputs, DataMap& outputs) const override;
};
// CollectHoistsState traverses the AST top-down, identifying which expressions
@@ -669,12 +669,15 @@
}
return nullptr;
});
-
- ctx.Clone();
}
};
-void DecomposeSideEffects::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+Transform::ApplyResult DecomposeSideEffects::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
// First collect side-effecting expressions to hoist
CollectHoistsState collect_hoists_state{ctx};
auto to_hoist = collect_hoists_state.Run();
@@ -682,6 +685,9 @@
// Now decompose these expressions
DecomposeState decompose_state{ctx, std::move(to_hoist)};
decompose_state.Run();
+
+ ctx.Clone();
+ return Program(std::move(b));
}
} // namespace
@@ -689,13 +695,13 @@
PromoteSideEffectsToDecl::PromoteSideEffectsToDecl() = default;
PromoteSideEffectsToDecl::~PromoteSideEffectsToDecl() = default;
-Output PromoteSideEffectsToDecl::Run(const Program* program, const DataMap& data) const {
+Transform::ApplyResult PromoteSideEffectsToDecl::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap& outputs) const {
transform::Manager manager;
manager.Add<SimplifySideEffectStatements>();
manager.Add<DecomposeSideEffects>();
-
- auto output = manager.Run(program, data);
- return output;
+ return manager.Apply(src, inputs, outputs);
}
} // namespace tint::transform
diff --git a/src/tint/transform/promote_side_effects_to_decl.h b/src/tint/transform/promote_side_effects_to_decl.h
index d5d1126..99e80c6 100644
--- a/src/tint/transform/promote_side_effects_to_decl.h
+++ b/src/tint/transform/promote_side_effects_to_decl.h
@@ -31,12 +31,10 @@
/// Destructor
~PromoteSideEffectsToDecl() override;
- protected:
- /// Runs the transform on `program`, returning the transformation result.
- /// @param program the source program to transform
- /// @param data optional extra transform-specific data
- /// @returns the transformation result
- Output Run(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/remove_continue_in_switch.cc b/src/tint/transform/remove_continue_in_switch.cc
index e5df23f..cf0158f 100644
--- a/src/tint/transform/remove_continue_in_switch.cc
+++ b/src/tint/transform/remove_continue_in_switch.cc
@@ -32,53 +32,19 @@
TINT_INSTANTIATE_TYPEINFO(tint::transform::RemoveContinueInSwitch);
namespace tint::transform {
-namespace {
-class State {
- private:
- CloneContext& ctx;
- ProgramBuilder& b;
- const sem::Info& sem;
-
- // Map of switch statement to 'tint_continue' variable.
- std::unordered_map<const ast::SwitchStatement*, Symbol> switch_to_cont_var_name;
-
- // If `cont` is within a switch statement within a loop, returns a pointer to
- // that switch statement.
- static const ast::SwitchStatement* GetParentSwitchInLoop(const sem::Info& sem,
- const ast::ContinueStatement* cont) {
- // Find whether first parent is a switch or a loop
- auto* sem_stmt = sem.Get(cont);
- auto* sem_parent = sem_stmt->FindFirstParent<sem::SwitchStatement, sem::LoopBlockStatement,
- sem::ForLoopStatement, sem::WhileStatement>();
- if (!sem_parent) {
- return nullptr;
- }
- return sem_parent->Declaration()->As<ast::SwitchStatement>();
- }
-
- public:
+/// PIMPL state for the transform
+struct RemoveContinueInSwitch::State {
/// Constructor
- /// @param ctx_in the context
- explicit State(CloneContext& ctx_in) : ctx(ctx_in), b(*ctx_in.dst), sem(ctx_in.src->Sem()) {}
-
- /// Returns true if this transform should be run for the given program
- static bool ShouldRun(const Program* program) {
- for (auto* node : program->ASTNodes().Objects()) {
- auto* stmt = node->As<ast::ContinueStatement>();
- if (!stmt) {
- continue;
- }
- if (GetParentSwitchInLoop(program->Sem(), stmt)) {
- return true;
- }
- }
- return false;
- }
+ /// @param program the source program
+ explicit State(const Program* program) : src(program) {}
/// Runs the transform
- void Run() {
- for (auto* node : ctx.src->ASTNodes().Objects()) {
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
+ bool made_changes = false;
+
+ for (auto* node : src->ASTNodes().Objects()) {
auto* cont = node->As<ast::ContinueStatement>();
if (!cont) {
continue;
@@ -90,6 +56,8 @@
continue;
}
+ made_changes = true;
+
auto cont_var_name =
tint::utils::GetOrCreate(switch_to_cont_var_name, switch_stmt, [&]() {
// Create and insert 'var tint_continue : bool = false;' before the
@@ -116,22 +84,50 @@
ctx.Replace(cont, new_stmt);
}
+ if (!made_changes) {
+ return SkipTransform;
+ }
+
ctx.Clone();
+ return Program(std::move(b));
+ }
+
+ private:
+ /// The source program
+ const Program* const src;
+ /// The target program builder
+ ProgramBuilder b;
+ /// The clone context
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
+ /// Alias to src->sem
+ const sem::Info& sem = src->Sem();
+
+ // Map of switch statement to 'tint_continue' variable.
+ std::unordered_map<const ast::SwitchStatement*, Symbol> switch_to_cont_var_name;
+
+ // If `cont` is within a switch statement within a loop, returns a pointer to
+ // that switch statement.
+ static const ast::SwitchStatement* GetParentSwitchInLoop(const sem::Info& sem,
+ const ast::ContinueStatement* cont) {
+ // Find whether first parent is a switch or a loop
+ auto* sem_stmt = sem.Get(cont);
+ auto* sem_parent = sem_stmt->FindFirstParent<sem::SwitchStatement, sem::LoopBlockStatement,
+ sem::ForLoopStatement, sem::WhileStatement>();
+ if (!sem_parent) {
+ return nullptr;
+ }
+ return sem_parent->Declaration()->As<ast::SwitchStatement>();
}
};
-} // namespace
-
RemoveContinueInSwitch::RemoveContinueInSwitch() = default;
RemoveContinueInSwitch::~RemoveContinueInSwitch() = default;
-bool RemoveContinueInSwitch::ShouldRun(const Program* program, const DataMap& /*data*/) const {
- return State::ShouldRun(program);
-}
-
-void RemoveContinueInSwitch::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- State state(ctx);
- state.Run();
+Transform::ApplyResult RemoveContinueInSwitch::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ State state(src);
+ return state.Run();
}
} // namespace tint::transform
diff --git a/src/tint/transform/remove_continue_in_switch.h b/src/tint/transform/remove_continue_in_switch.h
index 9e5a4d5..1070906 100644
--- a/src/tint/transform/remove_continue_in_switch.h
+++ b/src/tint/transform/remove_continue_in_switch.h
@@ -31,19 +31,13 @@
/// Destructor
~RemoveContinueInSwitch() override;
- protected:
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ private:
+ struct State;
};
} // namespace tint::transform
diff --git a/src/tint/transform/remove_phonies.cc b/src/tint/transform/remove_phonies.cc
index 1f84538..080152c 100644
--- a/src/tint/transform/remove_phonies.cc
+++ b/src/tint/transform/remove_phonies.cc
@@ -41,34 +41,25 @@
RemovePhonies::~RemovePhonies() = default;
-bool RemovePhonies::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* node : program->ASTNodes().Objects()) {
- if (node->Is<ast::PhonyExpression>()) {
- return true;
- }
- if (auto* stmt = node->As<ast::CallStatement>()) {
- if (program->Sem().Get(stmt->expr)->ConstantValue() != nullptr) {
- return true;
- }
- }
- }
- return false;
-}
+Transform::ApplyResult RemovePhonies::Apply(const Program* src, const DataMap&, DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
-void RemovePhonies::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- auto& sem = ctx.src->Sem();
+ auto& sem = src->Sem();
- std::unordered_map<SinkSignature, Symbol, utils::Hasher<SinkSignature>> sinks;
+ utils::Hashmap<SinkSignature, Symbol, 8, utils::Hasher<SinkSignature>> sinks;
- for (auto* node : ctx.src->ASTNodes().Objects()) {
+ bool made_changes = false;
+ for (auto* node : src->ASTNodes().Objects()) {
Switch(
node,
[&](const ast::AssignmentStatement* stmt) {
if (stmt->lhs->Is<ast::PhonyExpression>()) {
+ made_changes = true;
+
std::vector<const ast::Expression*> side_effects;
if (!ast::TraverseExpressions(
- stmt->rhs, ctx.dst->Diagnostics(),
- [&](const ast::CallExpression* expr) {
+ stmt->rhs, b.Diagnostics(), [&](const ast::CallExpression* expr) {
// ast::CallExpression may map to a function or builtin call
// (both may have side-effects), or a type initializer or
// type conversion (both do not have side effects).
@@ -100,8 +91,7 @@
if (auto* call = side_effects[0]->As<ast::CallExpression>()) {
// Phony assignment with single call side effect.
// Replace phony assignment with call.
- ctx.Replace(stmt,
- [&, call] { return ctx.dst->CallStmt(ctx.Clone(call)); });
+ ctx.Replace(stmt, [&, call] { return b.CallStmt(ctx.Clone(call)); });
return;
}
}
@@ -114,22 +104,21 @@
for (auto* arg : side_effects) {
sig.push_back(sem.Get(arg)->Type()->UnwrapRef());
}
- auto sink = utils::GetOrCreate(sinks, sig, [&] {
- auto name = ctx.dst->Symbols().New("phony_sink");
+ auto sink = sinks.GetOrCreate(sig, [&] {
+ auto name = b.Symbols().New("phony_sink");
utils::Vector<const ast::Parameter*, 8> params;
for (auto* ty : sig) {
auto* ast_ty = CreateASTTypeFor(ctx, ty);
- params.Push(
- ctx.dst->Param("p" + std::to_string(params.Length()), ast_ty));
+ params.Push(b.Param("p" + std::to_string(params.Length()), ast_ty));
}
- ctx.dst->Func(name, params, ctx.dst->ty.void_(), {});
+ b.Func(name, params, b.ty.void_(), {});
return name;
});
utils::Vector<const ast::Expression*, 8> args;
for (auto* arg : side_effects) {
args.Push(ctx.Clone(arg));
}
- return ctx.dst->CallStmt(ctx.dst->Call(sink, args));
+ return b.CallStmt(b.Call(sink, args));
});
}
},
@@ -138,12 +127,18 @@
// TODO(crbug.com/tint/1637): Remove if `stmt->expr` has no side-effects.
auto* sem_expr = sem.Get(stmt->expr);
if ((sem_expr->ConstantValue() != nullptr) && !sem_expr->HasSideEffects()) {
+ made_changes = true;
ctx.Remove(sem.Get(stmt)->Block()->Declaration()->statements, stmt);
}
});
}
+ if (!made_changes) {
+ return SkipTransform;
+ }
+
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/remove_phonies.h b/src/tint/transform/remove_phonies.h
index daa1812..99a049e 100644
--- a/src/tint/transform/remove_phonies.h
+++ b/src/tint/transform/remove_phonies.h
@@ -33,19 +33,10 @@
/// Destructor
~RemovePhonies() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/remove_unreachable_statements.cc b/src/tint/transform/remove_unreachable_statements.cc
index 964d767..f9bf202 100644
--- a/src/tint/transform/remove_unreachable_statements.cc
+++ b/src/tint/transform/remove_unreachable_statements.cc
@@ -36,27 +36,28 @@
RemoveUnreachableStatements::~RemoveUnreachableStatements() = default;
-bool RemoveUnreachableStatements::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* node : program->ASTNodes().Objects()) {
- if (auto* stmt = program->Sem().Get<sem::Statement>(node)) {
+Transform::ApplyResult RemoveUnreachableStatements::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
+ bool made_changes = false;
+ for (auto* node : src->ASTNodes().Objects()) {
+ if (auto* stmt = src->Sem().Get<sem::Statement>(node)) {
if (!stmt->IsReachable()) {
- return true;
+ RemoveStatement(ctx, stmt->Declaration());
+ made_changes = true;
}
}
}
- return false;
-}
-void RemoveUnreachableStatements::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- for (auto* node : ctx.src->ASTNodes().Objects()) {
- if (auto* stmt = ctx.src->Sem().Get<sem::Statement>(node)) {
- if (!stmt->IsReachable()) {
- RemoveStatement(ctx, stmt->Declaration());
- }
- }
+ if (!made_changes) {
+ return SkipTransform;
}
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/remove_unreachable_statements.h b/src/tint/transform/remove_unreachable_statements.h
index 7f8b947..f5848f5 100644
--- a/src/tint/transform/remove_unreachable_statements.h
+++ b/src/tint/transform/remove_unreachable_statements.h
@@ -32,19 +32,10 @@
/// Destructor
~RemoveUnreachableStatements() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/renamer.cc b/src/tint/transform/renamer.cc
index 562a52f..0fd1113 100644
--- a/src/tint/transform/renamer.cc
+++ b/src/tint/transform/renamer.cc
@@ -1252,39 +1252,31 @@
Renamer::Renamer() = default;
Renamer::~Renamer() = default;
-Output Renamer::Run(const Program* in, const DataMap& inputs) const {
- ProgramBuilder out;
- // Disable auto-cloning of symbols, since we want to rename them.
- CloneContext ctx(&out, in, false);
+Transform::ApplyResult Renamer::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap& outputs) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ false};
// Swizzles, builtin calls and builtin structure members need to keep their
// symbols preserved.
- std::unordered_set<const ast::IdentifierExpression*> preserve;
- for (auto* node : in->ASTNodes().Objects()) {
+ utils::Hashset<const ast::IdentifierExpression*, 8> preserve;
+ for (auto* node : src->ASTNodes().Objects()) {
if (auto* member = node->As<ast::MemberAccessorExpression>()) {
- auto* sem = in->Sem().Get(member);
- if (!sem) {
- TINT_ICE(Transform, out.Diagnostics())
- << "MemberAccessorExpression has no semantic info";
- continue;
- }
+ auto* sem = src->Sem().Get(member);
if (sem->Is<sem::Swizzle>()) {
- preserve.emplace(member->member);
- } else if (auto* str_expr = in->Sem().Get(member->structure)) {
+ preserve.Add(member->member);
+ } else if (auto* str_expr = src->Sem().Get(member->structure)) {
if (auto* ty = str_expr->Type()->UnwrapRef()->As<sem::Struct>()) {
if (ty->Declaration() == nullptr) { // Builtin structure
- preserve.emplace(member->member);
+ preserve.Add(member->member);
}
}
}
} else if (auto* call = node->As<ast::CallExpression>()) {
- auto* sem = in->Sem().Get(call)->UnwrapMaterialize()->As<sem::Call>();
- if (!sem) {
- TINT_ICE(Transform, out.Diagnostics()) << "CallExpression has no semantic info";
- continue;
- }
+ auto* sem = src->Sem().Get(call)->UnwrapMaterialize()->As<sem::Call>();
if (sem->Target()->Is<sem::Builtin>()) {
- preserve.emplace(call->target.name);
+ preserve.Add(call->target.name);
}
}
}
@@ -1300,7 +1292,7 @@
}
ctx.ReplaceAll([&](Symbol sym_in) {
- auto name_in = ctx.src->Symbols().NameFor(sym_in);
+ auto name_in = src->Symbols().NameFor(sym_in);
if (preserve_unicode || text::utf8::IsASCII(name_in)) {
switch (target) {
case Target::kAll:
@@ -1343,17 +1335,20 @@
});
ctx.ReplaceAll([&](const ast::IdentifierExpression* ident) -> const ast::IdentifierExpression* {
- if (preserve.count(ident)) {
+ if (preserve.Contains(ident)) {
auto sym_in = ident->symbol;
- auto str = in->Symbols().NameFor(sym_in);
- auto sym_out = out.Symbols().Register(str);
+ auto str = src->Symbols().NameFor(sym_in);
+ auto sym_out = b.Symbols().Register(str);
return ctx.dst->create<ast::IdentifierExpression>(ctx.Clone(ident->source), sym_out);
}
return nullptr; // Clone ident. Uses the symbol remapping above.
});
- ctx.Clone();
- return Output(Program(std::move(out)), std::make_unique<Data>(std::move(remappings)));
+ ctx.Clone(); // Must come before the std::move()
+
+ outputs.Add<Data>(std::move(remappings));
+
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/renamer.h b/src/tint/transform/renamer.h
index 000aee9..8a9f97e 100644
--- a/src/tint/transform/renamer.h
+++ b/src/tint/transform/renamer.h
@@ -85,11 +85,10 @@
/// Destructor
~Renamer() override;
- /// Runs the transform on `program`, returning the transformation result.
- /// @param program the source program to transform
- /// @param data optional extra transform-specific input data
- /// @returns the transformation result
- Output Run(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/robustness.cc b/src/tint/transform/robustness.cc
index a22f84f..75d63f2 100644
--- a/src/tint/transform/robustness.cc
+++ b/src/tint/transform/robustness.cc
@@ -33,36 +33,48 @@
namespace tint::transform {
-/// State holds the current transform state
+/// PIMPL state for the transform
struct Robustness::State {
- /// The clone context
- CloneContext& ctx;
+ /// Constructor
+ /// @param program the source program
+ /// @param omitted the omitted address spaces
+ State(const Program* program, std::unordered_set<ast::AddressSpace>&& omitted)
+ : src(program), omitted_address_spaces(std::move(omitted)) {}
- /// Set of address spacees to not apply the transform to
- std::unordered_set<ast::AddressSpace> omitted_classes;
-
- /// Applies the transformation state to `ctx`.
- void Transform() {
+ /// Runs the transform
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
ctx.ReplaceAll([&](const ast::IndexAccessorExpression* expr) { return Transform(expr); });
ctx.ReplaceAll([&](const ast::CallExpression* expr) { return Transform(expr); });
+
+ ctx.Clone();
+ return Program(std::move(b));
}
+ private:
+ /// The source program
+ const Program* const src;
+ /// The target program builder
+ ProgramBuilder b;
+ /// The clone context
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
+
+ /// Set of address spaces to not apply the transform to
+ std::unordered_set<ast::AddressSpace> omitted_address_spaces;
+
/// Apply bounds clamping to array, vector and matrix indexing
/// @param expr the array, vector or matrix index expression
/// @return the clamped replacement expression, or nullptr if `expr` should be cloned without
/// changes.
const ast::IndexAccessorExpression* Transform(const ast::IndexAccessorExpression* expr) {
- auto* sem =
- ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::IndexAccessorExpression>();
+ auto* sem = src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::IndexAccessorExpression>();
auto* ret_type = sem->Type();
auto* ref = ret_type->As<sem::Reference>();
- if (ref && omitted_classes.count(ref->AddressSpace()) != 0) {
+ if (ref && omitted_address_spaces.count(ref->AddressSpace()) != 0) {
return nullptr;
}
- ProgramBuilder& b = *ctx.dst;
-
// idx return the cloned index expression, as a u32.
auto idx = [&]() -> const ast::Expression* {
auto* i = ctx.Clone(expr->index);
@@ -109,8 +121,8 @@
} else {
// Note: Don't be tempted to use the array override variable as an expression
// here, the name might be shadowed!
- ctx.dst->Diagnostics().add_error(diag::System::Transform,
- sem::Array::kErrExpectedConstantCount);
+ b.Diagnostics().add_error(diag::System::Transform,
+ sem::Array::kErrExpectedConstantCount);
return nullptr;
}
@@ -119,7 +131,7 @@
[&](Default) {
TINT_ICE(Transform, b.Diagnostics())
<< "unhandled object type in robustness of array index: "
- << ctx.src->FriendlyName(ret_type->UnwrapRef());
+ << src->FriendlyName(ret_type->UnwrapRef());
return nullptr;
});
@@ -127,9 +139,9 @@
return nullptr; // Clamping not needed
}
- auto src = ctx.Clone(expr->source);
- auto* obj = ctx.Clone(expr->object);
- return b.IndexAccessor(src, obj, clamped_idx);
+ auto idx_src = ctx.Clone(expr->source);
+ auto* idx_obj = ctx.Clone(expr->object);
+ return b.IndexAccessor(idx_src, idx_obj, clamped_idx);
}
/// @param type builtin type
@@ -145,15 +157,13 @@
/// @return the clamped replacement call expression, or nullptr if `expr`
/// should be cloned without changes.
const ast::CallExpression* Transform(const ast::CallExpression* expr) {
- auto* call = ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
+ auto* call = src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
auto* call_target = call->Target();
auto* builtin = call_target->As<sem::Builtin>();
if (!builtin || !TextureBuiltinNeedsClamping(builtin->Type())) {
return nullptr; // No transform, just clone.
}
- ProgramBuilder& b = *ctx.dst;
-
// Indices of the mandatory texture and coords parameters, and the optional
// array and level parameters.
auto& signature = builtin->Signature();
@@ -261,7 +271,7 @@
// Clamp the level argument, if provided
if (level_idx >= 0) {
auto* arg = expr->args[static_cast<size_t>(level_idx)];
- ctx.Replace(arg, level_arg ? level_arg() : ctx.dst->Expr(0_a));
+ ctx.Replace(arg, level_arg ? level_arg() : b.Expr(0_a));
}
return nullptr; // Clone, which will use the argument replacements above.
@@ -276,28 +286,27 @@
Robustness::Robustness() = default;
Robustness::~Robustness() = default;
-void Robustness::Run(CloneContext& ctx, const DataMap& inputs, DataMap&) const {
+Transform::ApplyResult Robustness::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap&) const {
Config cfg;
if (auto* cfg_data = inputs.Get<Config>()) {
cfg = *cfg_data;
}
- std::unordered_set<ast::AddressSpace> omitted_classes;
- for (auto sc : cfg.omitted_classes) {
+ std::unordered_set<ast::AddressSpace> omitted_address_spaces;
+ for (auto sc : cfg.omitted_address_spaces) {
switch (sc) {
case AddressSpace::kUniform:
- omitted_classes.insert(ast::AddressSpace::kUniform);
+ omitted_address_spaces.insert(ast::AddressSpace::kUniform);
break;
case AddressSpace::kStorage:
- omitted_classes.insert(ast::AddressSpace::kStorage);
+ omitted_address_spaces.insert(ast::AddressSpace::kStorage);
break;
}
}
- State state{ctx, std::move(omitted_classes)};
-
- state.Transform();
- ctx.Clone();
+ return State{src, std::move(omitted_address_spaces)}.Run();
}
} // namespace tint::transform
diff --git a/src/tint/transform/robustness.h b/src/tint/transform/robustness.h
index 21a7ff9..14c5fe1 100644
--- a/src/tint/transform/robustness.h
+++ b/src/tint/transform/robustness.h
@@ -54,9 +54,9 @@
/// @returns this Config
Config& operator=(const Config&);
- /// Address spacees to omit from apply the transform to.
+ /// Address spaces to omit from apply the transform to.
/// This allows for optimizing on hardware that provide safe accesses.
- std::unordered_set<AddressSpace> omitted_classes;
+ std::unordered_set<AddressSpace> omitted_address_spaces;
};
/// Constructor
@@ -64,14 +64,10 @@
/// Destructor
~Robustness() override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
private:
struct State;
diff --git a/src/tint/transform/robustness_test.cc b/src/tint/transform/robustness_test.cc
index 16d958f..990bbde 100644
--- a/src/tint/transform/robustness_test.cc
+++ b/src/tint/transform/robustness_test.cc
@@ -1274,7 +1274,7 @@
)";
Robustness::Config cfg;
- cfg.omitted_classes.insert(Robustness::AddressSpace::kStorage);
+ cfg.omitted_address_spaces.insert(Robustness::AddressSpace::kStorage);
DataMap data;
data.Add<Robustness::Config>(cfg);
@@ -1325,7 +1325,7 @@
)";
Robustness::Config cfg;
- cfg.omitted_classes.insert(Robustness::AddressSpace::kUniform);
+ cfg.omitted_address_spaces.insert(Robustness::AddressSpace::kUniform);
DataMap data;
data.Add<Robustness::Config>(cfg);
@@ -1376,8 +1376,8 @@
)";
Robustness::Config cfg;
- cfg.omitted_classes.insert(Robustness::AddressSpace::kStorage);
- cfg.omitted_classes.insert(Robustness::AddressSpace::kUniform);
+ cfg.omitted_address_spaces.insert(Robustness::AddressSpace::kStorage);
+ cfg.omitted_address_spaces.insert(Robustness::AddressSpace::kUniform);
DataMap data;
data.Add<Robustness::Config>(cfg);
diff --git a/src/tint/transform/simplify_pointers.cc b/src/tint/transform/simplify_pointers.cc
index ea35699..b2b99ed 100644
--- a/src/tint/transform/simplify_pointers.cc
+++ b/src/tint/transform/simplify_pointers.cc
@@ -45,14 +45,18 @@
} // namespace
-/// The PIMPL state for the SimplifyPointers transform
+/// PIMPL state for the transform
struct SimplifyPointers::State {
+ /// The source program
+ const Program* const src;
+ /// The target program builder
+ ProgramBuilder b;
/// The clone context
- CloneContext& ctx;
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
/// Constructor
- /// @param context the clone context
- explicit State(CloneContext& context) : ctx(context) {}
+ /// @param program the source program
+ explicit State(const Program* program) : src(program) {}
/// Traverses the expression `expr` looking for non-literal array indexing
/// expressions that would affect the computed address of a pointer
@@ -120,10 +124,11 @@
}
}
- /// Performs the transformation
- void Run() {
+ /// Runs the transform
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
// A map of saved expressions to their saved variable name
- std::unordered_map<const ast::Expression*, Symbol> saved_vars;
+ utils::Hashmap<const ast::Expression*, Symbol, 8> saved_vars;
// Register the ast::Expression transform handler.
// This performs two different transformations:
@@ -135,9 +140,8 @@
// variable identifier.
ctx.ReplaceAll([&](const ast::Expression* expr) -> const ast::Expression* {
// Look to see if we need to swap this Expression with a saved variable.
- auto it = saved_vars.find(expr);
- if (it != saved_vars.end()) {
- return ctx.dst->Expr(it->second);
+ if (auto* saved_var = saved_vars.Find(expr)) {
+ return ctx.dst->Expr(*saved_var);
}
// Reduce the expression, folding away chains of address-of / indirections
@@ -174,7 +178,7 @@
// Scan the initializer expression for array index expressions that need
// to be hoist to temporary "saved" variables.
- std::vector<const ast::VariableDeclStatement*> saved;
+ utils::Vector<const ast::VariableDeclStatement*, 8> saved;
CollectSavedArrayIndices(
var->Declaration()->initializer, [&](const ast::Expression* idx_expr) {
// We have a sub-expression that needs to be saved.
@@ -182,18 +186,18 @@
auto saved_name = ctx.dst->Symbols().New(
ctx.src->Symbols().NameFor(var->Declaration()->symbol) + "_save");
auto* decl = ctx.dst->Decl(ctx.dst->Let(saved_name, ctx.Clone(idx_expr)));
- saved.emplace_back(decl);
+ saved.Push(decl);
// Record the substitution of `idx_expr` to the saved variable
// with the symbol `saved_name`. This will be used by the
// ReplaceAll() handler above.
- saved_vars.emplace(idx_expr, saved_name);
+ saved_vars.Add(idx_expr, saved_name);
});
// Find the place to insert the saved declarations.
// Special care needs to be made for lets declared as the initializer
// part of for-loops. In this case the block will hold the for-loop
// statement, not the let.
- if (!saved.empty()) {
+ if (!saved.IsEmpty()) {
auto* stmt = ctx.src->Sem().Get(let);
auto* block = stmt->Block();
// Find the statement owned by the block (either the let decl or a
@@ -219,7 +223,9 @@
RemoveStatement(ctx, let);
}
}
+
ctx.Clone();
+ return Program(std::move(b));
}
};
@@ -227,8 +233,8 @@
SimplifyPointers::~SimplifyPointers() = default;
-void SimplifyPointers::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- State(ctx).Run();
+Transform::ApplyResult SimplifyPointers::Apply(const Program* src, const DataMap&, DataMap&) const {
+ return State(src).Run();
}
} // namespace tint::transform
diff --git a/src/tint/transform/simplify_pointers.h b/src/tint/transform/simplify_pointers.h
index 787c7d8..6e040bb 100644
--- a/src/tint/transform/simplify_pointers.h
+++ b/src/tint/transform/simplify_pointers.h
@@ -39,16 +39,13 @@
/// Destructor
~SimplifyPointers() override;
- protected:
- struct State;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ private:
+ struct State;
};
} // namespace tint::transform
diff --git a/src/tint/transform/single_entry_point.cc b/src/tint/transform/single_entry_point.cc
index 8d26a7f..87787ae 100644
--- a/src/tint/transform/single_entry_point.cc
+++ b/src/tint/transform/single_entry_point.cc
@@ -30,33 +30,37 @@
SingleEntryPoint::~SingleEntryPoint() = default;
-void SingleEntryPoint::Run(CloneContext& ctx, const DataMap& inputs, DataMap&) const {
+Transform::ApplyResult SingleEntryPoint::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
auto* cfg = inputs.Get<Config>();
if (cfg == nullptr) {
- ctx.dst->Diagnostics().add_error(
- diag::System::Transform, "missing transform data for " + std::string(TypeInfo().name));
-
- return;
+ b.Diagnostics().add_error(diag::System::Transform,
+ "missing transform data for " + std::string(TypeInfo().name));
+ return Program(std::move(b));
}
// Find the target entry point.
const ast::Function* entry_point = nullptr;
- for (auto* f : ctx.src->AST().Functions()) {
+ for (auto* f : src->AST().Functions()) {
if (!f->IsEntryPoint()) {
continue;
}
- if (ctx.src->Symbols().NameFor(f->symbol) == cfg->entry_point_name) {
+ if (src->Symbols().NameFor(f->symbol) == cfg->entry_point_name) {
entry_point = f;
break;
}
}
if (entry_point == nullptr) {
- ctx.dst->Diagnostics().add_error(diag::System::Transform,
- "entry point '" + cfg->entry_point_name + "' not found");
- return;
+ b.Diagnostics().add_error(diag::System::Transform,
+ "entry point '" + cfg->entry_point_name + "' not found");
+ return Program(std::move(b));
}
- auto& sem = ctx.src->Sem();
+ auto& sem = src->Sem();
// Build set of referenced module-scope variables for faster lookups later.
std::unordered_set<const ast::Variable*> referenced_vars;
@@ -66,12 +70,12 @@
// Clone any module-scope variables, types, and functions that are statically referenced by the
// target entry point.
- for (auto* decl : ctx.src->AST().GlobalDeclarations()) {
+ for (auto* decl : src->AST().GlobalDeclarations()) {
Switch(
decl, //
[&](const ast::TypeDecl* ty) {
// TODO(jrprice): Strip unused types.
- ctx.dst->AST().AddTypeDecl(ctx.Clone(ty));
+ b.AST().AddTypeDecl(ctx.Clone(ty));
},
[&](const ast::Override* override) {
if (referenced_vars.count(override)) {
@@ -80,37 +84,39 @@
// so that its allocated ID so that it won't be affected by other
// stripped away overrides
auto* global = sem.Get(override);
- const auto* id = ctx.dst->Id(global->OverrideId());
+ const auto* id = b.Id(global->OverrideId());
ctx.InsertFront(override->attributes, id);
}
- ctx.dst->AST().AddGlobalVariable(ctx.Clone(override));
+ b.AST().AddGlobalVariable(ctx.Clone(override));
}
},
[&](const ast::Var* var) {
if (referenced_vars.count(var)) {
- ctx.dst->AST().AddGlobalVariable(ctx.Clone(var));
+ b.AST().AddGlobalVariable(ctx.Clone(var));
}
},
[&](const ast::Const* c) {
// Always keep 'const' declarations, as these can be used by attributes and array
// sizes, which are not tracked as transitively used by functions. They also don't
// typically get emitted by the backend unless they're actually used.
- ctx.dst->AST().AddGlobalVariable(ctx.Clone(c));
+ b.AST().AddGlobalVariable(ctx.Clone(c));
},
[&](const ast::Function* func) {
if (sem.Get(func)->HasAncestorEntryPoint(entry_point->symbol)) {
- ctx.dst->AST().AddFunction(ctx.Clone(func));
+ b.AST().AddFunction(ctx.Clone(func));
}
},
- [&](const ast::Enable* ext) { ctx.dst->AST().AddEnable(ctx.Clone(ext)); },
+ [&](const ast::Enable* ext) { b.AST().AddEnable(ctx.Clone(ext)); },
[&](Default) {
- TINT_UNREACHABLE(Transform, ctx.dst->Diagnostics())
+ TINT_UNREACHABLE(Transform, b.Diagnostics())
<< "unhandled global declaration: " << decl->TypeInfo().name;
});
}
// Clone the entry point.
- ctx.dst->AST().AddFunction(ctx.Clone(entry_point));
+ b.AST().AddFunction(ctx.Clone(entry_point));
+
+ return Program(std::move(b));
}
SingleEntryPoint::Config::Config(std::string entry_point) : entry_point_name(entry_point) {}
diff --git a/src/tint/transform/single_entry_point.h b/src/tint/transform/single_entry_point.h
index 59aa021..7aba5e8 100644
--- a/src/tint/transform/single_entry_point.h
+++ b/src/tint/transform/single_entry_point.h
@@ -53,14 +53,10 @@
/// Destructor
~SingleEntryPoint() override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/spirv_atomic.cc b/src/tint/transform/spirv_atomic.cc
index 127c702..eba6681 100644
--- a/src/tint/transform/spirv_atomic.cc
+++ b/src/tint/transform/spirv_atomic.cc
@@ -37,7 +37,7 @@
using namespace tint::number_suffixes; // NOLINT
-/// Private implementation of transform
+/// PIMPL state for the transform
struct SpirvAtomic::State {
private:
/// A struct that has been forked because a subset of members were made atomic.
@@ -46,19 +46,24 @@
std::unordered_set<size_t> atomic_members;
};
- CloneContext& ctx;
- ProgramBuilder& b = *ctx.dst;
+ /// The source program
+ const Program* const src;
+ /// The target program builder
+ ProgramBuilder b;
+ /// The clone context
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
std::unordered_map<const ast::Struct*, ForkedStruct> forked_structs;
std::unordered_set<const sem::Variable*> atomic_variables;
utils::UniqueVector<const sem::Expression*, 8> atomic_expressions;
public:
/// Constructor
- /// @param c the clone context
- explicit State(CloneContext& c) : ctx(c) {}
+ /// @param program the source program
+ explicit State(const Program* program) : src(program) {}
/// Runs the transform
- void Run() {
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
// Look for stub functions generated by the SPIR-V reader, which are used as placeholders
// for atomic builtin calls.
for (auto* fn : ctx.src->AST().Functions()) {
@@ -102,6 +107,10 @@
}
}
+ if (atomic_expressions.IsEmpty()) {
+ return SkipTransform;
+ }
+
// Transform all variables and structure members that were used in atomic operations as
// atomic types. This propagates up originating expression chains.
ProcessAtomicExpressions();
@@ -143,6 +152,7 @@
ReplaceLoadsAndStores();
ctx.Clone();
+ return Program(std::move(b));
}
private:
@@ -297,17 +307,8 @@
ctx->dst->AllocateNodeID(), builtin);
}
-bool SpirvAtomic::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* fn : program->AST().Functions()) {
- if (ast::HasAttribute<Stub>(fn->attributes)) {
- return true;
- }
- }
- return false;
-}
-
-void SpirvAtomic::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- State{ctx}.Run();
+Transform::ApplyResult SpirvAtomic::Apply(const Program* src, const DataMap&, DataMap&) const {
+ return State{src}.Run();
}
} // namespace tint::transform
diff --git a/src/tint/transform/spirv_atomic.h b/src/tint/transform/spirv_atomic.h
index e1311c5..0f99dba 100644
--- a/src/tint/transform/spirv_atomic.h
+++ b/src/tint/transform/spirv_atomic.h
@@ -63,21 +63,13 @@
const sem::BuiltinType builtin;
};
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- protected:
+ private:
struct State;
-
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/std140.cc b/src/tint/transform/std140.cc
index 920fc69..0746bda 100644
--- a/src/tint/transform/std140.cc
+++ b/src/tint/transform/std140.cc
@@ -77,14 +77,20 @@
namespace tint::transform {
-/// The PIMPL state for the Std140 transform
+/// PIMPL state for the transform
struct Std140::State {
/// Constructor
- /// @param c the CloneContext
- explicit State(CloneContext& c) : ctx(c) {}
+ /// @param program the source program
+ explicit State(const Program* program) : src(program) {}
/// Runs the transform
- void Run() {
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
+ if (!ShouldRun()) {
+ // Transform is not required
+ return SkipTransform;
+ }
+
// Begin by creating forked types for any type that is used as a uniform buffer, that
// either directly or transitively contains a matrix that needs splitting for std140 layout.
ForkTypes();
@@ -116,11 +122,11 @@
});
ctx.Clone();
+ return Program(std::move(b));
}
/// @returns true if this transform should be run for the given program
- /// @param program the program to inspect
- static bool ShouldRun(const Program* program) {
+ bool ShouldRun() const {
// Returns true if the type needs to be forked for std140 usage.
auto needs_fork = [&](const sem::Type* ty) {
while (auto* arr = ty->As<sem::Array>()) {
@@ -135,7 +141,7 @@
};
// Scan structures for members that need forking
- for (auto* ty : program->Types()) {
+ for (auto* ty : src->Types()) {
if (auto* str = ty->As<sem::Struct>()) {
if (str->UsedAs(ast::AddressSpace::kUniform)) {
for (auto* member : str->Members()) {
@@ -148,8 +154,8 @@
}
// Scan uniform variables that have types that need forking
- for (auto* decl : program->AST().GlobalVariables()) {
- auto* global = program->Sem().Get(decl);
+ for (auto* decl : src->AST().GlobalVariables()) {
+ auto* global = src->Sem().Get(decl);
if (global->AddressSpace() == ast::AddressSpace::kUniform) {
if (needs_fork(global->Type()->UnwrapRef())) {
return true;
@@ -197,14 +203,16 @@
}
};
+ /// The source program
+ const Program* const src;
+ /// The target program builder
+ ProgramBuilder b;
/// The clone context
- CloneContext& ctx;
- /// Alias to the semantic info in ctx.src
- const sem::Info& sem = ctx.src->Sem();
- /// Alias to the symbols in ctx.src
- const SymbolTable& sym = ctx.src->Symbols();
- /// Alias to the ctx.dst program builder
- ProgramBuilder& b = *ctx.dst;
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
+ /// Alias to the semantic info in src
+ const sem::Info& sem = src->Sem();
+ /// Alias to the symbols in src
+ const SymbolTable& sym = src->Symbols();
/// Map of load function signature, to the generated function
utils::Hashmap<LoadFnKey, Symbol, 8, LoadFnKey::Hasher> load_fns;
@@ -218,7 +226,7 @@
// Map of original structure to 'std140' forked structure
utils::Hashmap<const sem::Struct*, Symbol, 8> std140_structs;
- // Map of structure member in ctx.src of a matrix type, to list of decomposed column
+ // Map of structure member in src of a matrix type, to list of decomposed column
// members in ctx.dst.
utils::Hashmap<const sem::StructMember*, utils::Vector<const ast::StructMember*, 4>, 8>
std140_mat_members;
@@ -232,7 +240,7 @@
utils::Vector<Symbol, 4> columns;
};
- // Map of matrix type in ctx.src, to decomposed column structure in ctx.dst.
+ // Map of matrix type in src, to decomposed column structure in ctx.dst.
utils::Hashmap<const sem::Matrix*, Std140Matrix, 8> std140_mats;
/// AccessChain describes a chain of access expressions to uniform buffer variable.
@@ -266,7 +274,7 @@
/// map (via Std140Type()).
void ForkTypes() {
// For each module scope declaration...
- for (auto* global : ctx.src->Sem().Module()->DependencyOrderedDeclarations()) {
+ for (auto* global : src->Sem().Module()->DependencyOrderedDeclarations()) {
// Check to see if this is a structure used by a uniform buffer...
auto* str = sem.Get<sem::Struct>(global);
if (str && str->UsedAs(ast::AddressSpace::kUniform)) {
@@ -317,7 +325,7 @@
if (fork_std140) {
// Clone any members that have not already been cloned.
for (auto& member : members) {
- if (member->program_id == ctx.src->ID()) {
+ if (member->program_id == src->ID()) {
member = ctx.Clone(member);
}
}
@@ -326,7 +334,7 @@
auto name = b.Symbols().New(sym.NameFor(str->Name()) + "_std140");
auto* std140 = b.create<ast::Struct>(name, std::move(members),
ctx.Clone(str->Declaration()->attributes));
- ctx.InsertAfter(ctx.src->AST().GlobalDeclarations(), global, std140);
+ ctx.InsertAfter(src->AST().GlobalDeclarations(), global, std140);
std140_structs.Add(str, name);
}
}
@@ -337,14 +345,13 @@
/// type that has been forked for std140-layout.
/// Populates the #std140_uniforms set.
void ReplaceUniformVarTypes() {
- for (auto* global : ctx.src->AST().GlobalVariables()) {
+ for (auto* global : src->AST().GlobalVariables()) {
if (auto* var = global->As<ast::Var>()) {
if (var->declared_address_space == ast::AddressSpace::kUniform) {
auto* v = sem.Get(var);
if (auto* std140_ty = Std140Type(v->Type()->UnwrapRef())) {
ctx.Replace(global->type, std140_ty);
std140_uniforms.Add(v);
- continue;
}
}
}
@@ -404,7 +411,7 @@
auto std140_mat = std140_mats.GetOrCreate(mat, [&] {
auto name = b.Symbols().New("mat" + std::to_string(mat->columns()) + "x" +
std::to_string(mat->rows()) + "_" +
- ctx.src->FriendlyName(mat->type()));
+ src->FriendlyName(mat->type()));
auto members =
DecomposedMatrixStructMembers(mat, "col", mat->Align(), mat->Size());
b.Structure(name, members);
@@ -421,7 +428,7 @@
if (auto* std140 = Std140Type(arr->ElemType())) {
utils::Vector<const ast::Attribute*, 1> attrs;
if (!arr->IsStrideImplicit()) {
- attrs.Push(ctx.dst->create<ast::StrideAttribute>(arr->Stride()));
+ attrs.Push(b.create<ast::StrideAttribute>(arr->Stride()));
}
auto count = arr->ConstantCount();
if (!count) {
@@ -429,7 +436,7 @@
// * Override-expression counts can only be applied to workgroup arrays, and
// this method only handles types transitively used as uniform buffers.
// * Runtime-sized arrays cannot be used in uniform buffers.
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "unexpected non-constant array count";
count = 1;
}
@@ -440,7 +447,7 @@
});
}
- /// @param mat the matrix to decompose (in ctx.src)
+ /// @param mat the matrix to decompose (in src)
/// @param name_prefix the name prefix to apply to each of the returned column vector members.
/// @param align the alignment in bytes of the matrix.
/// @param size the size in bytes of the matrix.
@@ -473,7 +480,7 @@
// Build the member
const auto col_name = name_prefix + std::to_string(i);
const auto* col_ty = CreateASTTypeFor(ctx, mat->ColumnType());
- const auto* col_member = ctx.dst->Member(col_name, col_ty, std::move(attributes));
+ const auto* col_member = b.Member(col_name, col_ty, std::move(attributes));
// Record the member for std140_mat_members
out.Push(col_member);
}
@@ -618,7 +625,7 @@
/// @returns a name suffix for a std140 -> non-std140 conversion function based on the type
/// being converted.
- const std::string ConvertSuffix(const sem::Type* ty) const {
+ const std::string ConvertSuffix(const sem::Type* ty) {
return Switch(
ty, //
[&](const sem::Struct* str) { return sym.NameFor(str->Name()); },
@@ -629,8 +636,7 @@
// * Override-expression counts can only be applied to workgroup arrays, and
// this method only handles types transitively used as uniform buffers.
// * Runtime-sized arrays cannot be used in uniform buffers.
- TINT_ICE(Transform, ctx.dst->Diagnostics())
- << "unexpected non-constant array count";
+ TINT_ICE(Transform, b.Diagnostics()) << "unexpected non-constant array count";
count = 1;
}
return "arr" + std::to_string(count.value()) + "_" + ConvertSuffix(arr->ElemType());
@@ -642,7 +648,7 @@
[&](const sem::F32*) { return "f32"; },
[&](Default) {
TINT_ICE(Transform, b.Diagnostics())
- << "unhandled type for conversion name: " << ctx.src->FriendlyName(ty);
+ << "unhandled type for conversion name: " << src->FriendlyName(ty);
return "";
});
}
@@ -718,8 +724,7 @@
stmts.Push(b.Return(b.Construct(mat_ty, std::move(mat_args))));
} else {
TINT_ICE(Transform, b.Diagnostics())
- << "failed to find std140 matrix info for: "
- << ctx.src->FriendlyName(ty);
+ << "failed to find std140 matrix info for: " << src->FriendlyName(ty);
}
}, //
[&](const sem::Array* arr) {
@@ -736,7 +741,7 @@
// * Override-expression counts can only be applied to workgroup arrays, and
// this method only handles types transitively used as uniform buffers.
// * Runtime-sized arrays cannot be used in uniform buffers.
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "unexpected non-constant array count";
count = 1;
}
@@ -749,7 +754,7 @@
},
[&](Default) {
TINT_ICE(Transform, b.Diagnostics())
- << "unhandled type for conversion: " << ctx.src->FriendlyName(ty);
+ << "unhandled type for conversion: " << src->FriendlyName(ty);
});
// Generate the function
@@ -1063,7 +1068,7 @@
if (std::get_if<UniformVariable>(&access)) {
const auto* expr = b.Expr(ctx.Clone(chain.var->Declaration()->symbol));
- const auto name = ctx.src->Symbols().NameFor(chain.var->Declaration()->symbol);
+ const auto name = src->Symbols().NameFor(chain.var->Declaration()->symbol);
ty = chain.var->Type()->UnwrapRef();
return {expr, ty, name};
}
@@ -1090,7 +1095,7 @@
}, //
[&](Default) -> ExprTypeName {
TINT_ICE(Transform, b.Diagnostics())
- << "unhandled type for access chain: " << ctx.src->FriendlyName(ty);
+ << "unhandled type for access chain: " << src->FriendlyName(ty);
return {};
});
}
@@ -1104,14 +1109,14 @@
for (auto el : *swizzle) {
rhs += xyzw[el];
}
- auto swizzle_ty = ctx.src->Types().Find<sem::Vector>(
+ auto swizzle_ty = src->Types().Find<sem::Vector>(
vec->type(), static_cast<uint32_t>(swizzle->Length()));
auto* expr = b.MemberAccessor(lhs, rhs);
return {expr, swizzle_ty, rhs};
}, //
[&](Default) -> ExprTypeName {
TINT_ICE(Transform, b.Diagnostics())
- << "unhandled type for access chain: " << ctx.src->FriendlyName(ty);
+ << "unhandled type for access chain: " << src->FriendlyName(ty);
return {};
});
}
@@ -1140,7 +1145,7 @@
}, //
[&](Default) -> ExprTypeName {
TINT_ICE(Transform, b.Diagnostics())
- << "unhandled type for access chain: " << ctx.src->FriendlyName(ty);
+ << "unhandled type for access chain: " << src->FriendlyName(ty);
return {};
});
}
@@ -1150,12 +1155,8 @@
Std140::~Std140() = default;
-bool Std140::ShouldRun(const Program* program, const DataMap&) const {
- return State::ShouldRun(program);
-}
-
-void Std140::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- State(ctx).Run();
+Transform::ApplyResult Std140::Apply(const Program* src, const DataMap&, DataMap&) const {
+ return State(src).Run();
}
} // namespace tint::transform
diff --git a/src/tint/transform/std140.h b/src/tint/transform/std140.h
index ec5cad5..49e663d 100644
--- a/src/tint/transform/std140.h
+++ b/src/tint/transform/std140.h
@@ -34,21 +34,13 @@
/// Destructor
~Std140() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
private:
struct State;
-
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/substitute_override.cc b/src/tint/transform/substitute_override.cc
index 2de04e0..7c2d0a2 100644
--- a/src/tint/transform/substitute_override.cc
+++ b/src/tint/transform/substitute_override.cc
@@ -15,6 +15,7 @@
#include "src/tint/transform/substitute_override.h"
#include <functional>
+#include <utility>
#include "src/tint/program_builder.h"
#include "src/tint/sem/builtin.h"
@@ -25,12 +26,9 @@
TINT_INSTANTIATE_TYPEINFO(tint::transform::SubstituteOverride::Config);
namespace tint::transform {
+namespace {
-SubstituteOverride::SubstituteOverride() = default;
-
-SubstituteOverride::~SubstituteOverride() = default;
-
-bool SubstituteOverride::ShouldRun(const Program* program, const DataMap&) const {
+bool ShouldRun(const Program* program) {
for (auto* node : program->AST().GlobalVariables()) {
if (node->Is<ast::Override>()) {
return true;
@@ -39,18 +37,32 @@
return false;
}
-void SubstituteOverride::Run(CloneContext& ctx, const DataMap& config, DataMap&) const {
+} // namespace
+
+SubstituteOverride::SubstituteOverride() = default;
+
+SubstituteOverride::~SubstituteOverride() = default;
+
+Transform::ApplyResult SubstituteOverride::Apply(const Program* src,
+ const DataMap& config,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
const auto* data = config.Get<Config>();
if (!data) {
- ctx.dst->Diagnostics().add_error(diag::System::Transform,
- "Missing override substitution data");
- return;
+ b.Diagnostics().add_error(diag::System::Transform, "Missing override substitution data");
+ return Program(std::move(b));
+ }
+
+ if (!ShouldRun(ctx.src)) {
+ return SkipTransform;
}
ctx.ReplaceAll([&](const ast::Override* w) -> const ast::Const* {
auto* sem = ctx.src->Sem().Get(w);
- auto src = ctx.Clone(w->source);
+ auto source = ctx.Clone(w->source);
auto sym = ctx.Clone(w->symbol);
auto* ty = ctx.Clone(w->type);
@@ -58,30 +70,30 @@
auto iter = data->map.find(sem->OverrideId());
if (iter == data->map.end()) {
if (!w->initializer) {
- ctx.dst->Diagnostics().add_error(
+ b.Diagnostics().add_error(
diag::System::Transform,
"Initializer not provided for override, and override not overridden.");
return nullptr;
}
- return ctx.dst->Const(src, sym, ty, ctx.Clone(w->initializer));
+ return b.Const(source, sym, ty, ctx.Clone(w->initializer));
}
auto value = iter->second;
auto* ctor = Switch(
sem->Type(),
- [&](const sem::Bool*) { return ctx.dst->Expr(!std::equal_to<double>()(value, 0.0)); },
- [&](const sem::I32*) { return ctx.dst->Expr(i32(value)); },
- [&](const sem::U32*) { return ctx.dst->Expr(u32(value)); },
- [&](const sem::F32*) { return ctx.dst->Expr(f32(value)); },
- [&](const sem::F16*) { return ctx.dst->Expr(f16(value)); });
+ [&](const sem::Bool*) { return b.Expr(!std::equal_to<double>()(value, 0.0)); },
+ [&](const sem::I32*) { return b.Expr(i32(value)); },
+ [&](const sem::U32*) { return b.Expr(u32(value)); },
+ [&](const sem::F32*) { return b.Expr(f32(value)); },
+ [&](const sem::F16*) { return b.Expr(f16(value)); });
if (!ctor) {
- ctx.dst->Diagnostics().add_error(diag::System::Transform,
- "Failed to create override-expression");
+ b.Diagnostics().add_error(diag::System::Transform,
+ "Failed to create override-expression");
return nullptr;
}
- return ctx.dst->Const(src, sym, ty, ctor);
+ return b.Const(source, sym, ty, ctor);
});
// Ensure that objects that are indexed with an override-expression are materialized.
@@ -89,11 +101,10 @@
// resulting type of the index may change. See: crbug.com/tint/1697.
ctx.ReplaceAll(
[&](const ast::IndexAccessorExpression* expr) -> const ast::IndexAccessorExpression* {
- if (auto* sem = ctx.src->Sem().Get(expr)) {
+ if (auto* sem = src->Sem().Get(expr)) {
if (auto* access = sem->UnwrapMaterialize()->As<sem::IndexAccessorExpression>()) {
if (access->Object()->UnwrapMaterialize()->Type()->HoldsAbstract() &&
access->Index()->Stage() == sem::EvaluationStage::kOverride) {
- auto& b = *ctx.dst;
auto* obj = b.Call(sem::str(sem::BuiltinType::kTintMaterialize),
ctx.Clone(expr->object));
return b.IndexAccessor(obj, ctx.Clone(expr->index));
@@ -104,6 +115,7 @@
});
ctx.Clone();
+ return Program(std::move(b));
}
SubstituteOverride::Config::Config() = default;
diff --git a/src/tint/transform/substitute_override.h b/src/tint/transform/substitute_override.h
index 940e11d..853acc7 100644
--- a/src/tint/transform/substitute_override.h
+++ b/src/tint/transform/substitute_override.h
@@ -75,19 +75,10 @@
/// Destructor
~SubstituteOverride() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/test_helper.h b/src/tint/transform/test_helper.h
index bc82fe5..ac48c5f 100644
--- a/src/tint/transform/test_helper.h
+++ b/src/tint/transform/test_helper.h
@@ -122,7 +122,18 @@
}
const Transform& t = TRANSFORM();
- return t.ShouldRun(&program, data);
+
+ DataMap outputs;
+ auto result = t.Apply(&program, data, outputs);
+ if (!result) {
+ return false;
+ }
+ if (!result->IsValid()) {
+ ADD_FAILURE() << "Apply() called by ShouldRun() returned errors: "
+ << result->Diagnostics().str();
+ return true;
+ }
+ return result.has_value();
}
/// @param in the input WGSL source
diff --git a/src/tint/transform/transform.cc b/src/tint/transform/transform.cc
index 3e03411..c37f3b4 100644
--- a/src/tint/transform/transform.cc
+++ b/src/tint/transform/transform.cc
@@ -46,24 +46,19 @@
Transform::Transform() = default;
Transform::~Transform() = default;
-Output Transform::Run(const Program* program, const DataMap& data /* = {} */) const {
- ProgramBuilder builder;
- CloneContext ctx(&builder, program);
+Output Transform::Run(const Program* src, const DataMap& data /* = {} */) const {
Output output;
- Run(ctx, data, output.data);
- output.program = Program(std::move(builder));
+ if (auto program = Apply(src, data, output.data)) {
+ output.program = std::move(program.value());
+ } else {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+ ctx.Clone();
+ output.program = Program(std::move(b));
+ }
return output;
}
-void Transform::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- TINT_UNIMPLEMENTED(Transform, ctx.dst->Diagnostics())
- << "Transform::Run() unimplemented for " << TypeInfo().name;
-}
-
-bool Transform::ShouldRun(const Program*, const DataMap&) const {
- return true;
-}
-
void Transform::RemoveStatement(CloneContext& ctx, const ast::Statement* stmt) {
auto* sem = ctx.src->Sem().Get(stmt);
if (auto* block = tint::As<sem::BlockStatement>(sem->Parent())) {
diff --git a/src/tint/transform/transform.h b/src/tint/transform/transform.h
index c3e3d1d..6580e25 100644
--- a/src/tint/transform/transform.h
+++ b/src/tint/transform/transform.h
@@ -158,26 +158,30 @@
/// Destructor
~Transform() override;
- /// Runs the transform on `program`, returning the transformation result.
+ /// Runs the transform on @p program, returning the transformation result or a clone of
+ /// @p program.
/// @param program the source program to transform
/// @param data optional extra transform-specific input data
/// @returns the transformation result
- virtual Output Run(const Program* program, const DataMap& data = {}) const;
+ Output Run(const Program* program, const DataMap& data = {}) const;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- virtual bool ShouldRun(const Program* program, const DataMap& data = {}) const;
+ /// The return value of Apply().
+ /// If SkipTransform (std::nullopt), then the transform is not needed to be run.
+ using ApplyResult = std::optional<Program>;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
+ /// Value returned from Apply() to indicate that the transform does not need to be run
+ static inline constexpr std::nullopt_t SkipTransform = std::nullopt;
+
+ /// Runs the transform on `program`, return.
+ /// @param program the input program
/// @param inputs optional extra transform-specific input data
/// @param outputs optional extra transform-specific output data
- virtual void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const;
+ /// @returns a transformed program, or std::nullopt if the transform didn't need to run.
+ virtual ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const = 0;
+ protected:
/// Removes the statement `stmt` from the transformed program.
/// RemoveStatement handles edge cases, like statements in the initializer and
/// continuing of for-loops.
diff --git a/src/tint/transform/transform_test.cc b/src/tint/transform/transform_test.cc
index d063ba2..82fdf6a 100644
--- a/src/tint/transform/transform_test.cc
+++ b/src/tint/transform/transform_test.cc
@@ -23,7 +23,9 @@
// Inherit from Transform so we have access to protected methods
struct CreateASTTypeForTest : public testing::Test, public Transform {
- Output Run(const Program*, const DataMap&) const override { return {}; }
+ ApplyResult Apply(const Program*, const DataMap&, DataMap&) const override {
+ return SkipTransform;
+ }
const ast::Type* create(std::function<sem::Type*(ProgramBuilder&)> create_sem_type) {
ProgramBuilder sem_type_builder;
diff --git a/src/tint/transform/unshadow.cc b/src/tint/transform/unshadow.cc
index 975e2ed..93ce595 100644
--- a/src/tint/transform/unshadow.cc
+++ b/src/tint/transform/unshadow.cc
@@ -28,27 +28,32 @@
namespace tint::transform {
-/// The PIMPL state for the Unshadow transform
+/// PIMPL state for the transform
struct Unshadow::State {
+ /// The source program
+ const Program* const src;
+ /// The target program builder
+ ProgramBuilder b;
/// The clone context
- CloneContext& ctx;
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
/// Constructor
- /// @param context the clone context
- explicit State(CloneContext& context) : ctx(context) {}
+ /// @param program the source program
+ explicit State(const Program* program) : src(program) {}
- /// Performs the transformation
- void Run() {
- auto& sem = ctx.src->Sem();
+ /// Runs the transform
+ /// @returns the new program or SkipTransform if the transform is not required
+ Transform::ApplyResult Run() {
+ auto& sem = src->Sem();
// Maps a variable to its new name.
- std::unordered_map<const sem::Variable*, Symbol> renamed_to;
+ utils::Hashmap<const sem::Variable*, Symbol, 8> renamed_to;
auto rename = [&](const sem::Variable* v) -> const ast::Variable* {
auto* decl = v->Declaration();
- auto name = ctx.src->Symbols().NameFor(decl->symbol);
- auto symbol = ctx.dst->Symbols().New(name);
- renamed_to.emplace(v, symbol);
+ auto name = src->Symbols().NameFor(decl->symbol);
+ auto symbol = b.Symbols().New(name);
+ renamed_to.Add(v, symbol);
auto source = ctx.Clone(decl->source);
auto* type = ctx.Clone(decl->type);
@@ -57,20 +62,20 @@
return Switch(
decl, //
[&](const ast::Var* var) {
- return ctx.dst->Var(source, symbol, type, var->declared_address_space,
- var->declared_access, initializer, attributes);
+ return b.Var(source, symbol, type, var->declared_address_space,
+ var->declared_access, initializer, attributes);
},
[&](const ast::Let*) {
- return ctx.dst->Let(source, symbol, type, initializer, attributes);
+ return b.Let(source, symbol, type, initializer, attributes);
},
[&](const ast::Const*) {
- return ctx.dst->Const(source, symbol, type, initializer, attributes);
+ return b.Const(source, symbol, type, initializer, attributes);
},
- [&](const ast::Parameter*) {
- return ctx.dst->Param(source, symbol, type, attributes);
+ [&](const ast::Parameter*) { //
+ return b.Param(source, symbol, type, attributes);
},
[&](Default) {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "unexpected variable type: " << decl->TypeInfo().name;
return nullptr;
});
@@ -92,14 +97,15 @@
ctx.ReplaceAll(
[&](const ast::IdentifierExpression* ident) -> const tint::ast::IdentifierExpression* {
if (auto* user = sem.Get<sem::VariableUser>(ident)) {
- auto it = renamed_to.find(user->Variable());
- if (it != renamed_to.end()) {
- return ctx.dst->Expr(it->second);
+ if (auto* renamed = renamed_to.Find(user->Variable())) {
+ return b.Expr(*renamed);
}
}
return nullptr;
});
+
ctx.Clone();
+ return Program(std::move(b));
}
};
@@ -107,8 +113,8 @@
Unshadow::~Unshadow() = default;
-void Unshadow::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- State(ctx).Run();
+Transform::ApplyResult Unshadow::Apply(const Program* src, const DataMap&, DataMap&) const {
+ return State(src).Run();
}
} // namespace tint::transform
diff --git a/src/tint/transform/unshadow.h b/src/tint/transform/unshadow.h
index 5ffe839..8ebf105 100644
--- a/src/tint/transform/unshadow.h
+++ b/src/tint/transform/unshadow.h
@@ -29,16 +29,13 @@
/// Destructor
~Unshadow() override;
- protected:
- struct State;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ private:
+ struct State;
};
} // namespace tint::transform
diff --git a/src/tint/transform/unwind_discard_functions.cc b/src/tint/transform/unwind_discard_functions.cc
index 4e20d55..068fe35 100644
--- a/src/tint/transform/unwind_discard_functions.cc
+++ b/src/tint/transform/unwind_discard_functions.cc
@@ -35,7 +35,51 @@
namespace tint::transform {
namespace {
-class State {
+bool ShouldRun(const Program* program) {
+ auto& sem = program->Sem();
+ for (auto* f : program->AST().Functions()) {
+ if (sem.Get(f)->Behaviors().Contains(sem::Behavior::kDiscard)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+/// PIMPL state for the transform
+struct UnwindDiscardFunctions::State {
+ /// Constructor
+ /// @param ctx_in the context
+ explicit State(CloneContext& ctx_in) : ctx(ctx_in), b(*ctx_in.dst), sem(ctx_in.src->Sem()) {}
+
+ /// Runs the transform
+ void Run() {
+ ctx.ReplaceAll([&](const ast::BlockStatement* block) -> const ast::Statement* {
+ // Iterate block statements and replace them as needed.
+ for (auto* stmt : block->statements) {
+ if (auto* new_stmt = Statement(stmt)) {
+ ctx.Replace(stmt, new_stmt);
+ }
+
+ // Handle for loops, as they are the only other AST node that
+ // contains statements outside of BlockStatements.
+ if (auto* fl = stmt->As<ast::ForLoopStatement>()) {
+ if (auto* new_stmt = Statement(fl->initializer)) {
+ ctx.Replace(fl->initializer, new_stmt);
+ }
+ if (auto* new_stmt = Statement(fl->continuing)) {
+ // NOTE: Should never reach here as we cannot discard in a
+ // continuing block.
+ ctx.Replace(fl->continuing, new_stmt);
+ }
+ }
+ }
+
+ return nullptr;
+ });
+ }
+
private:
CloneContext& ctx;
ProgramBuilder& b;
@@ -163,7 +207,7 @@
// Returns true if `stmt` is a for-loop initializer statement.
bool IsForLoopInitStatement(const ast::Statement* stmt) {
if (auto* sem_stmt = sem.Get(stmt)) {
- if (auto* sem_fl = As<sem::ForLoopStatement>(sem_stmt->Parent())) {
+ if (auto* sem_fl = tint::As<sem::ForLoopStatement>(sem_stmt->Parent())) {
return sem_fl->Declaration()->initializer == stmt;
}
}
@@ -305,60 +349,26 @@
return TryInsertAfter(s, sem_expr);
});
}
-
- public:
- /// Constructor
- /// @param ctx_in the context
- explicit State(CloneContext& ctx_in) : ctx(ctx_in), b(*ctx_in.dst), sem(ctx_in.src->Sem()) {}
-
- /// Runs the transform
- void Run() {
- ctx.ReplaceAll([&](const ast::BlockStatement* block) -> const ast::Statement* {
- // Iterate block statements and replace them as needed.
- for (auto* stmt : block->statements) {
- if (auto* new_stmt = Statement(stmt)) {
- ctx.Replace(stmt, new_stmt);
- }
-
- // Handle for loops, as they are the only other AST node that
- // contains statements outside of BlockStatements.
- if (auto* fl = stmt->As<ast::ForLoopStatement>()) {
- if (auto* new_stmt = Statement(fl->initializer)) {
- ctx.Replace(fl->initializer, new_stmt);
- }
- if (auto* new_stmt = Statement(fl->continuing)) {
- // NOTE: Should never reach here as we cannot discard in a
- // continuing block.
- ctx.Replace(fl->continuing, new_stmt);
- }
- }
- }
-
- return nullptr;
- });
-
- ctx.Clone();
- }
};
-} // namespace
-
UnwindDiscardFunctions::UnwindDiscardFunctions() = default;
UnwindDiscardFunctions::~UnwindDiscardFunctions() = default;
-void UnwindDiscardFunctions::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+Transform::ApplyResult UnwindDiscardFunctions::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
+ }
+
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
State state(ctx);
state.Run();
-}
-bool UnwindDiscardFunctions::ShouldRun(const Program* program, const DataMap& /*data*/) const {
- auto& sem = program->Sem();
- for (auto* f : program->AST().Functions()) {
- if (sem.Get(f)->Behaviors().Contains(sem::Behavior::kDiscard)) {
- return true;
- }
- }
- return false;
+ ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/unwind_discard_functions.h b/src/tint/transform/unwind_discard_functions.h
index 105a9d8..7614c27 100644
--- a/src/tint/transform/unwind_discard_functions.h
+++ b/src/tint/transform/unwind_discard_functions.h
@@ -44,19 +44,13 @@
/// Destructor
~UnwindDiscardFunctions() override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+ private:
+ struct State;
};
} // namespace tint::transform
diff --git a/src/tint/transform/utils/hoist_to_decl_before.cc b/src/tint/transform/utils/hoist_to_decl_before.cc
index 85bd2b2..e0b35a1 100644
--- a/src/tint/transform/utils/hoist_to_decl_before.cc
+++ b/src/tint/transform/utils/hoist_to_decl_before.cc
@@ -14,7 +14,7 @@
#include "src/tint/transform/utils/hoist_to_decl_before.h"
-#include <unordered_map>
+#include <utility>
#include "src/tint/program_builder.h"
#include "src/tint/sem/block_statement.h"
@@ -23,12 +23,66 @@
#include "src/tint/sem/reference.h"
#include "src/tint/sem/variable.h"
#include "src/tint/sem/while_statement.h"
+#include "src/tint/utils/hashmap.h"
#include "src/tint/utils/reverse.h"
+#include "src/tint/utils/transform.h"
namespace tint::transform {
/// Private implementation of HoistToDeclBefore transform
-class HoistToDeclBefore::State {
+struct HoistToDeclBefore::State {
+ /// Constructor
+ /// @param ctx_in the clone context
+ explicit State(CloneContext& ctx_in) : ctx(ctx_in), b(*ctx_in.dst) {}
+
+ /// @copydoc HoistToDeclBefore::Add()
+ bool Add(const sem::Expression* before_expr,
+ const ast::Expression* expr,
+ bool as_let,
+ const char* decl_name) {
+ auto name = b.Symbols().New(decl_name);
+
+ if (as_let) {
+ auto builder = [this, expr, name] {
+ return b.Decl(b.Let(name, ctx.CloneWithoutTransform(expr)));
+ };
+ if (!InsertBeforeImpl(before_expr->Stmt(), std::move(builder))) {
+ return false;
+ }
+ } else {
+ auto builder = [this, expr, name] {
+ return b.Decl(b.Var(name, ctx.CloneWithoutTransform(expr)));
+ };
+ if (!InsertBeforeImpl(before_expr->Stmt(), std::move(builder))) {
+ return false;
+ }
+ }
+
+ // Replace the initializer expression with a reference to the let
+ ctx.Replace(expr, b.Expr(name));
+ return true;
+ }
+
+ /// @copydoc HoistToDeclBefore::InsertBefore(const sem::Statement*, const ast::Statement*)
+ bool InsertBefore(const sem::Statement* before_stmt, const ast::Statement* stmt) {
+ if (stmt) {
+ auto builder = [stmt] { return stmt; };
+ return InsertBeforeImpl(before_stmt, std::move(builder));
+ }
+ return InsertBeforeImpl(before_stmt, Decompose{});
+ }
+
+ /// @copydoc HoistToDeclBefore::InsertBefore(const sem::Statement*, const StmtBuilder&)
+ bool InsertBefore(const sem::Statement* before_stmt, const StmtBuilder& builder) {
+ return InsertBeforeImpl(before_stmt, std::move(builder));
+ }
+
+ /// @copydoc HoistToDeclBefore::Prepare()
+ bool Prepare(const sem::Expression* before_expr) {
+ return InsertBefore(before_expr->Stmt(), nullptr);
+ }
+
+ private:
CloneContext& ctx;
ProgramBuilder& b;
@@ -36,46 +90,78 @@
/// loop, so that declaration statements can be inserted before the
/// condition expression or continuing statement.
struct LoopInfo {
- utils::Vector<const ast::Statement*, 8> cond_decls;
- utils::Vector<const ast::Statement*, 8> cont_decls;
+ utils::Vector<StmtBuilder, 8> cond_decls;
+ utils::Vector<StmtBuilder, 8> cont_decls;
};
/// Info for each else-if that needs decomposing
struct ElseIfInfo {
/// Decls to insert before condition
- utils::Vector<const ast::Statement*, 8> cond_decls;
+ utils::Vector<StmtBuilder, 8> cond_decls;
};
/// For-loops that need to be decomposed to loops.
- std::unordered_map<const sem::ForLoopStatement*, LoopInfo> for_loops;
+ utils::Hashmap<const sem::ForLoopStatement*, LoopInfo, 4> for_loops;
/// Whiles that need to be decomposed to loops.
- std::unordered_map<const sem::WhileStatement*, LoopInfo> while_loops;
+ utils::Hashmap<const sem::WhileStatement*, LoopInfo, 4> while_loops;
/// 'else if' statements that need to be decomposed to 'else {if}'
- std::unordered_map<const ast::IfStatement*, ElseIfInfo> else_ifs;
+ utils::Hashmap<const ast::IfStatement*, ElseIfInfo, 4> else_ifs;
- // Converts any for-loops marked for conversion to loops, inserting
- // registered declaration statements before the condition or continuing
- // statement.
- void ForLoopsToLoops() {
- if (for_loops.empty()) {
- return;
+ template <size_t N>
+ static auto Build(const utils::Vector<StmtBuilder, N>& builders) {
+ return utils::Transform(builders, [&](auto& builder) { return builder(); });
+ }
+
+ /// @returns a new LoopInfo reference for the given @p for_loop.
+ /// @note if this is the first call to this method, then RegisterForLoopTransform() is
+ /// automatically called.
+ /// @warning the returned reference is invalid if this is called a second time, or the
+ /// #for_loops map is mutated.
+ LoopInfo& ForLoop(const sem::ForLoopStatement* for_loop) {
+ if (for_loops.IsEmpty()) {
+ RegisterForLoopTransform();
}
+ return for_loops.GetOrZero(for_loop);
+ }
- // At least one for-loop needs to be transformed into a loop.
+ /// @returns a new LoopInfo reference for the given @p while_loop.
+ /// @note if this is the first call to this method, then RegisterWhileLoopTransform() is
+ /// automatically called.
+ /// @warning the returned reference is invalid if this is called a second time, or the
+ /// #for_loops map is mutated.
+ LoopInfo& WhileLoop(const sem::WhileStatement* while_loop) {
+ if (while_loops.IsEmpty()) {
+ RegisterWhileLoopTransform();
+ }
+ return while_loops.GetOrZero(while_loop);
+ }
+
+ /// @returns a new ElseIfInfo reference for the given @p else_if.
+ /// @note if this is the first call to this method, then RegisterElseIfTransform() is
+ /// automatically called.
+ /// @warning the returned reference is invalid if this is called a second time, or the
+ /// #else_ifs map is mutated.
+ ElseIfInfo& ElseIf(const ast::IfStatement* else_if) {
+ if (else_ifs.IsEmpty()) {
+ RegisterElseIfTransform();
+ }
+ return else_ifs.GetOrZero(else_if);
+ }
+
+ /// Registers the handler for transforming for-loops based on the content of the #for_loops map.
+ void RegisterForLoopTransform() const {
ctx.ReplaceAll([&](const ast::ForLoopStatement* stmt) -> const ast::Statement* {
auto& sem = ctx.src->Sem();
if (auto* fl = sem.Get(stmt)) {
- if (auto it = for_loops.find(fl); it != for_loops.end()) {
- auto& info = it->second;
+ if (auto* info = for_loops.Find(fl)) {
auto* for_loop = fl->Declaration();
// For-loop needs to be decomposed to a loop.
// Build the loop body's statements.
- // Start with any let declarations for the conditional
- // expression.
- auto body_stmts = info.cond_decls;
+ // Start with any let declarations for the conditional expression.
+ auto body_stmts = Build(info->cond_decls);
// If the for-loop has a condition, emit this next as:
// if (!cond) { break; }
if (auto* cond = for_loop->condition) {
@@ -95,7 +181,7 @@
if (auto* cont = for_loop->continuing) {
// Continuing block starts with any let declarations used by
// the continuing.
- auto cont_stmts = info.cont_decls;
+ auto cont_stmts = Build(info->cont_decls);
cont_stmts.Push(ctx.Clone(cont));
continuing = b.Block(cont_stmts);
}
@@ -112,34 +198,29 @@
});
}
- // Converts any while-loops marked for conversion to loops, inserting
- // registered declaration statements before the condition.
- void WhilesToLoops() {
- if (while_loops.empty()) {
- return;
- }
-
+ /// Registers the handler for transforming while-loops based on the content of the #while_loops
+ /// map.
+ void RegisterWhileLoopTransform() const {
// At least one while needs to be transformed into a loop.
ctx.ReplaceAll([&](const ast::WhileStatement* stmt) -> const ast::Statement* {
auto& sem = ctx.src->Sem();
if (auto* w = sem.Get(stmt)) {
- if (auto it = while_loops.find(w); it != while_loops.end()) {
- auto& info = it->second;
+ if (auto* info = while_loops.Find(w)) {
auto* while_loop = w->Declaration();
// While needs to be decomposed to a loop.
// Build the loop body's statements.
// Start with any let declarations for the conditional
// expression.
- auto body_stmts = info.cond_decls;
+ auto body_stmts = utils::Transform(info->cond_decls,
+ [&](auto& builder) { return builder(); });
// Emit the condition as:
// if (!cond) { break; }
auto* cond = while_loop->condition;
// !condition
- auto* not_cond =
- b.create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, ctx.Clone(cond));
+ auto* not_cond = b.Not(ctx.Clone(cond));
// { break; }
- auto* break_body = b.Block(b.create<ast::BreakStatement>());
+ auto* break_body = b.Block(b.Break());
// if (!condition) { break; }
body_stmts.Push(b.If(not_cond, break_body));
@@ -157,81 +238,49 @@
});
}
- void ElseIfsToElseWithNestedIfs() {
+ /// Registers the handler for transforming if-statements based on the content of the #else_ifs
+ /// map.
+ void RegisterElseIfTransform() const {
// Decompose 'else-if' statements into 'else { if }' blocks.
- ctx.ReplaceAll([&](const ast::IfStatement* else_if) -> const ast::Statement* {
- if (!else_ifs.count(else_if)) {
- return nullptr;
+ ctx.ReplaceAll([&](const ast::IfStatement* stmt) -> const ast::Statement* {
+ if (auto* info = else_ifs.Find(stmt)) {
+ // Build the else block's body statements, starting with let decls for the
+ // conditional expression.
+ auto body_stmts = Build(info->cond_decls);
+
+ // Move the 'else-if' into the new `else` block as a plain 'if'.
+ auto* cond = ctx.Clone(stmt->condition);
+ auto* body = ctx.Clone(stmt->body);
+ auto* new_if = b.If(cond, body, b.Else(ctx.Clone(stmt->else_statement)));
+ body_stmts.Push(new_if);
+
+ // Replace the 'else-if' with the new 'else' block.
+ return b.Block(body_stmts);
}
- auto& else_if_info = else_ifs[else_if];
-
- // Build the else block's body statements, starting with let decls for
- // the conditional expression.
- auto& body_stmts = else_if_info.cond_decls;
-
- // Move the 'else-if' into the new `else` block as a plain 'if'.
- auto* cond = ctx.Clone(else_if->condition);
- auto* body = ctx.Clone(else_if->body);
- auto* new_if = b.If(cond, body, b.Else(ctx.Clone(else_if->else_statement)));
- body_stmts.Push(new_if);
-
- // Replace the 'else-if' with the new 'else' block.
- return b.Block(body_stmts);
+ return nullptr;
});
}
- public:
- /// Constructor
- /// @param ctx_in the clone context
- explicit State(CloneContext& ctx_in) : ctx(ctx_in), b(*ctx_in.dst) {}
+ /// A type used to signal to InsertBeforeImpl that no insertion should take place - instead flow
+ /// control statements should just be decomposed.
+ struct Decompose {};
- /// Hoists `expr` to a `let` or `var` with optional `decl_name`, inserting it
- /// before `before_expr`.
- /// @param before_expr expression to insert `expr` before
- /// @param expr expression to hoist
- /// @param as_let hoist to `let` if true, otherwise to `var`
- /// @param decl_name optional name to use for the variable/constant name
- /// @return true on success
- bool Add(const sem::Expression* before_expr,
- const ast::Expression* expr,
- bool as_let,
- const char* decl_name) {
- auto name = b.Symbols().New(decl_name);
+ template <typename BUILDER>
+ bool InsertBeforeImpl(const sem::Statement* before_stmt, BUILDER&& builder) {
+ (void)builder; // Avoid 'unused parameter' warning due to 'if constexpr'
- // Construct the let/var that holds the hoisted expr
- auto* v = as_let ? static_cast<const ast::Variable*>(b.Let(name, ctx.Clone(expr)))
- : static_cast<const ast::Variable*>(b.Var(name, ctx.Clone(expr)));
- auto* decl = b.Decl(v);
-
- if (!InsertBefore(before_expr->Stmt(), decl)) {
- return false;
- }
-
- // Replace the initializer expression with a reference to the let
- ctx.Replace(expr, b.Expr(name));
- return true;
- }
-
- /// Inserts `stmt` before `before_stmt`, possibly marking a for-loop to be
- /// converted to a loop, or an else-if to an else { if }. If `decl` is
- /// nullptr, for-loop and else-if conversions are marked, but no hoisting
- /// takes place.
- /// @param before_stmt statement to insert `stmt` before
- /// @param stmt statement to insert
- /// @return true on success
- bool InsertBefore(const sem::Statement* before_stmt, const ast::Statement* stmt) {
auto* ip = before_stmt->Declaration();
auto* else_if = before_stmt->As<sem::IfStatement>();
if (else_if && else_if->Parent()->Is<sem::IfStatement>()) {
// Insertion point is an 'else if' condition.
// Need to convert 'else if' to 'else { if }'.
- auto& else_if_info = else_ifs[else_if->Declaration()];
+ auto& else_if_info = ElseIf(else_if->Declaration());
// Index the map to convert this else if, even if `stmt` is nullptr.
auto& decls = else_if_info.cond_decls;
- if (stmt) {
- decls.Push(stmt);
+ if constexpr (!std::is_same_v<BUILDER, Decompose>) {
+ decls.Push(std::forward<BUILDER>(builder));
}
return true;
}
@@ -241,9 +290,9 @@
// For-loop needs to be decomposed to a loop.
// Index the map to convert this for-loop, even if `stmt` is nullptr.
- auto& decls = for_loops[fl].cond_decls;
- if (stmt) {
- decls.Push(stmt);
+ auto& decls = ForLoop(fl).cond_decls;
+ if constexpr (!std::is_same_v<BUILDER, Decompose>) {
+ decls.Push(std::forward<BUILDER>(builder));
}
return true;
}
@@ -253,9 +302,9 @@
// While needs to be decomposed to a loop.
// Index the map to convert this while, even if `stmt` is nullptr.
- auto& decls = while_loops[w].cond_decls;
- if (stmt) {
- decls.Push(stmt);
+ auto& decls = WhileLoop(w).cond_decls;
+ if constexpr (!std::is_same_v<BUILDER, Decompose>) {
+ decls.Push(std::forward<BUILDER>(builder));
}
return true;
}
@@ -264,8 +313,9 @@
if (auto* block = parent->As<sem::BlockStatement>()) {
// Insert point sits in a block. Simple case.
// Insert the stmt before the parent statement.
- if (stmt) {
- ctx.InsertBefore(block->Declaration()->statements, ip, stmt);
+ if constexpr (!std::is_same_v<BUILDER, Decompose>) {
+ ctx.InsertBefore(block->Declaration()->statements, ip,
+ std::forward<BUILDER>(builder));
}
return true;
}
@@ -276,9 +326,9 @@
if (fl->Declaration()->initializer == ip) {
// Insertion point is a for-loop initializer.
// Insert the new statement above the for-loop.
- if (stmt) {
+ if constexpr (!std::is_same_v<BUILDER, Decompose>) {
ctx.InsertBefore(fl->Block()->Declaration()->statements, fl->Declaration(),
- stmt);
+ std::forward<BUILDER>(builder));
}
return true;
}
@@ -288,9 +338,9 @@
// For-loop needs to be decomposed to a loop.
// Index the map to convert this for-loop, even if `stmt` is nullptr.
- auto& decls = for_loops[fl].cont_decls;
- if (stmt) {
- decls.Push(stmt);
+ auto& decls = ForLoop(fl).cont_decls;
+ if constexpr (!std::is_same_v<BUILDER, Decompose>) {
+ decls.Push(std::forward<BUILDER>(builder));
}
return true;
}
@@ -303,25 +353,6 @@
<< "unhandled expression parent statement type: " << parent->TypeInfo().name;
return false;
}
-
- /// Use to signal that we plan on hoisting a decl before `before_expr`. This
- /// will convert 'for-loop's to 'loop's and 'else-if's to 'else {if}'s if
- /// needed.
- /// @param before_expr expression we would hoist a decl before
- /// @return true on success
- bool Prepare(const sem::Expression* before_expr) {
- return InsertBefore(before_expr->Stmt(), nullptr);
- }
-
- /// Applies any scheduled insertions from previous calls to Add() to
- /// CloneContext. Call this once before ctx.Clone().
- /// @return true on success
- bool Apply() {
- ForLoopsToLoops();
- WhilesToLoops();
- ElseIfsToElseWithNestedIfs();
- return true;
- }
};
HoistToDeclBefore::HoistToDeclBefore(CloneContext& ctx) : state_(std::make_unique<State>(ctx)) {}
@@ -340,12 +371,13 @@
return state_->InsertBefore(before_stmt, stmt);
}
-bool HoistToDeclBefore::Prepare(const sem::Expression* before_expr) {
- return state_->Prepare(before_expr);
+bool HoistToDeclBefore::InsertBefore(const sem::Statement* before_stmt,
+ const StmtBuilder& builder) {
+ return state_->InsertBefore(before_stmt, builder);
}
-bool HoistToDeclBefore::Apply() {
- return state_->Apply();
+bool HoistToDeclBefore::Prepare(const sem::Expression* before_expr) {
+ return state_->Prepare(before_expr);
}
} // namespace tint::transform
diff --git a/src/tint/transform/utils/hoist_to_decl_before.h b/src/tint/transform/utils/hoist_to_decl_before.h
index d0b96e0..d9a8a8a 100644
--- a/src/tint/transform/utils/hoist_to_decl_before.h
+++ b/src/tint/transform/utils/hoist_to_decl_before.h
@@ -15,6 +15,7 @@
#ifndef SRC_TINT_TRANSFORM_UTILS_HOIST_TO_DECL_BEFORE_H_
#define SRC_TINT_TRANSFORM_UTILS_HOIST_TO_DECL_BEFORE_H_
+#include <functional>
#include <memory>
#include "src/tint/sem/expression.h"
@@ -34,25 +35,40 @@
/// Destructor
~HoistToDeclBefore();
- /// Hoists `expr` to a `let` or `var` with optional `decl_name`, inserting it
- /// before `before_expr`.
+ /// StmtBuilder is a builder of an AST statement
+ using StmtBuilder = std::function<const ast::Statement*()>;
+
+ /// Hoists @p expr to a `let` or `var` with optional `decl_name`, inserting it
+ /// before @p before_expr.
/// @param before_expr expression to insert `expr` before
/// @param expr expression to hoist
- /// @param as_const hoist to `let` if true, otherwise to `var`
+ /// @param as_let hoist to `let` if true, otherwise to `var`
/// @param decl_name optional name to use for the variable/constant name
/// @return true on success
bool Add(const sem::Expression* before_expr,
const ast::Expression* expr,
- bool as_const,
+ bool as_let,
const char* decl_name = "");
- /// Inserts `stmt` before `before_stmt`, possibly converting 'for-loop's to
- /// 'loop's if necessary.
- /// @param before_stmt statement to insert `stmt` before
+ /// Inserts @p stmt before @p before_stmt, possibly converting 'for-loop's to 'loop's if
+ /// necessary.
+ /// @warning If the container of @p before_stmt is cloned multiple times, then the resolver will
+ /// ICE as the same statement cannot be shared.
+ /// @param before_stmt statement to insert @p stmt before
/// @param stmt statement to insert
/// @return true on success
bool InsertBefore(const sem::Statement* before_stmt, const ast::Statement* stmt);
+ /// Inserts the returned statement of @p builder before @p before_stmt, possibly converting
+ /// 'for-loop's to 'loop's if necessary.
+ /// @note If the container of @p before_stmt is cloned multiple times, then @p builder will be
+ /// called for each clone.
+ /// @param before_stmt the preceding statement that the statement of @p builder will be inserted
+ /// before
+ /// @param builder the statement builder used to create the new statement
+ /// @return true on success
+ bool InsertBefore(const sem::Statement* before_stmt, const StmtBuilder& builder);
+
/// Use to signal that we plan on hoisting a decl before `before_expr`. This
/// will convert 'for-loop's to 'loop's and 'else-if's to 'else {if}'s if
/// needed.
@@ -60,13 +76,8 @@
/// @return true on success
bool Prepare(const sem::Expression* before_expr);
- /// Applies any scheduled insertions from previous calls to Add() to
- /// CloneContext. Call this once before ctx.Clone().
- /// @return true on success
- bool Apply();
-
private:
- class State;
+ struct State;
std::unique_ptr<State> state_;
};
diff --git a/src/tint/transform/utils/hoist_to_decl_before_test.cc b/src/tint/transform/utils/hoist_to_decl_before_test.cc
index f0d3b36..7b45e01 100644
--- a/src/tint/transform/utils/hoist_to_decl_before_test.cc
+++ b/src/tint/transform/utils/hoist_to_decl_before_test.cc
@@ -45,7 +45,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Add(sem_expr, expr, true);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -77,7 +76,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Add(sem_expr, expr, true);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -112,7 +110,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Add(sem_expr, expr, true);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -151,7 +148,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Add(sem_expr, expr, true);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -195,7 +191,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Add(sem_expr, expr, true);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -240,7 +235,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Add(sem_expr, expr, true);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -279,7 +273,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Add(sem_expr, expr, true);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -314,7 +307,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Add(sem_expr, expr, true);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -349,7 +341,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Prepare(sem_expr);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -387,7 +378,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Prepare(sem_expr);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -434,7 +424,6 @@
HoistToDeclBefore hoistToDeclBefore(ctx);
auto* sem_expr = ctx.src->Sem().Get(expr);
hoistToDeclBefore.Prepare(sem_expr);
- hoistToDeclBefore.Apply();
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -473,7 +462,42 @@
auto* before_stmt = ctx.src->Sem().Get(var);
auto* new_stmt = ctx.dst->CallStmt(ctx.dst->Call("foo"));
hoistToDeclBefore.InsertBefore(before_stmt, new_stmt);
- hoistToDeclBefore.Apply();
+
+ ctx.Clone();
+ Program cloned(std::move(cloned_b));
+
+ auto* expect = R"(
+fn foo() {
+}
+
+fn f() {
+ foo();
+ var a = 1i;
+}
+)";
+
+ EXPECT_EQ(expect, str(cloned));
+}
+
+TEST_F(HoistToDeclBeforeTest, InsertBefore_Block_Function) {
+ // fn foo() {
+ // }
+ // fn f() {
+ // var a = 1i;
+ // }
+ ProgramBuilder b;
+ b.Func("foo", utils::Empty, b.ty.void_(), utils::Empty);
+ auto* var = b.Decl(b.Var("a", b.Expr(1_i)));
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var});
+
+ Program original(std::move(b));
+ ProgramBuilder cloned_b;
+ CloneContext ctx(&cloned_b, &original);
+
+ HoistToDeclBefore hoistToDeclBefore(ctx);
+ auto* before_stmt = ctx.src->Sem().Get(var);
+ hoistToDeclBefore.InsertBefore(before_stmt,
+ [&] { return ctx.dst->CallStmt(ctx.dst->Call("foo")); });
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -512,7 +536,45 @@
auto* before_stmt = ctx.src->Sem().Get(var);
auto* new_stmt = ctx.dst->CallStmt(ctx.dst->Call("foo"));
hoistToDeclBefore.InsertBefore(before_stmt, new_stmt);
- hoistToDeclBefore.Apply();
+
+ ctx.Clone();
+ Program cloned(std::move(cloned_b));
+
+ auto* expect = R"(
+fn foo() {
+}
+
+fn f() {
+ foo();
+ for(var a = 1i; true; ) {
+ }
+}
+)";
+
+ EXPECT_EQ(expect, str(cloned));
+}
+
+TEST_F(HoistToDeclBeforeTest, InsertBefore_ForLoopInit_Function) {
+ // fn foo() {
+ // }
+ // fn f() {
+ // for(var a = 1i; true;) {
+ // }
+ // }
+ ProgramBuilder b;
+ b.Func("foo", utils::Empty, b.ty.void_(), utils::Empty);
+ auto* var = b.Decl(b.Var("a", b.Expr(1_i)));
+ auto* s = b.For(var, b.Expr(true), nullptr, b.Block());
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{s});
+
+ Program original(std::move(b));
+ ProgramBuilder cloned_b;
+ CloneContext ctx(&cloned_b, &original);
+
+ HoistToDeclBefore hoistToDeclBefore(ctx);
+ auto* before_stmt = ctx.src->Sem().Get(var);
+ hoistToDeclBefore.InsertBefore(before_stmt,
+ [&] { return ctx.dst->CallStmt(ctx.dst->Call("foo")); });
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -554,7 +616,57 @@
auto* before_stmt = ctx.src->Sem().Get(cont->As<ast::Statement>());
auto* new_stmt = ctx.dst->CallStmt(ctx.dst->Call("foo"));
hoistToDeclBefore.InsertBefore(before_stmt, new_stmt);
- hoistToDeclBefore.Apply();
+
+ ctx.Clone();
+ Program cloned(std::move(cloned_b));
+
+ auto* expect = R"(
+fn foo() {
+}
+
+fn f() {
+ var a = 1i;
+ loop {
+ if (!(true)) {
+ break;
+ }
+ {
+ }
+
+ continuing {
+ foo();
+ a += 1i;
+ }
+ }
+}
+)";
+
+ EXPECT_EQ(expect, str(cloned));
+}
+
+TEST_F(HoistToDeclBeforeTest, InsertBefore_ForLoopCont_Function) {
+ // fn foo() {
+ // }
+ // fn f() {
+ // var a = 1i;
+ // for(; true; a+=1i) {
+ // }
+ // }
+ ProgramBuilder b;
+ b.Func("foo", utils::Empty, b.ty.void_(), utils::Empty);
+ auto* var = b.Decl(b.Var("a", b.Expr(1_i)));
+ auto* cont = b.CompoundAssign("a", b.Expr(1_i), ast::BinaryOp::kAdd);
+ auto* s = b.For(nullptr, b.Expr(true), cont, b.Block());
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var, s});
+
+ Program original(std::move(b));
+ ProgramBuilder cloned_b;
+ CloneContext ctx(&cloned_b, &original);
+
+ HoistToDeclBefore hoistToDeclBefore(ctx);
+ auto* before_stmt = ctx.src->Sem().Get(cont->As<ast::Statement>());
+ hoistToDeclBefore.InsertBefore(before_stmt,
+ [&] { return ctx.dst->CallStmt(ctx.dst->Call("foo")); });
ctx.Clone();
Program cloned(std::move(cloned_b));
@@ -609,7 +721,55 @@
auto* before_stmt = ctx.src->Sem().Get(elseif);
auto* new_stmt = ctx.dst->CallStmt(ctx.dst->Call("foo"));
hoistToDeclBefore.InsertBefore(before_stmt, new_stmt);
- hoistToDeclBefore.Apply();
+
+ ctx.Clone();
+ Program cloned(std::move(cloned_b));
+
+ auto* expect = R"(
+fn foo() {
+}
+
+fn f() {
+ var a : bool;
+ if (true) {
+ } else {
+ foo();
+ if (a) {
+ } else {
+ }
+ }
+}
+)";
+
+ EXPECT_EQ(expect, str(cloned));
+}
+
+TEST_F(HoistToDeclBeforeTest, InsertBefore_ElseIf_Function) {
+ // fn foo() {
+ // }
+ // fn f() {
+ // var a : bool;
+ // if (true) {
+ // } else if (a) {
+ // } else {
+ // }
+ // }
+ ProgramBuilder b;
+ b.Func("foo", utils::Empty, b.ty.void_(), utils::Empty);
+ auto* var = b.Decl(b.Var("a", b.ty.bool_()));
+ auto* elseif = b.If(b.Expr("a"), b.Block(), b.Else(b.Block()));
+ auto* s = b.If(b.Expr(true), b.Block(), //
+ b.Else(elseif));
+ b.Func("f", utils::Empty, b.ty.void_(), utils::Vector{var, s});
+
+ Program original(std::move(b));
+ ProgramBuilder cloned_b;
+ CloneContext ctx(&cloned_b, &original);
+
+ HoistToDeclBefore hoistToDeclBefore(ctx);
+ auto* before_stmt = ctx.src->Sem().Get(elseif);
+ hoistToDeclBefore.InsertBefore(before_stmt,
+ [&] { return ctx.dst->CallStmt(ctx.dst->Call("foo")); });
ctx.Clone();
Program cloned(std::move(cloned_b));
diff --git a/src/tint/transform/var_for_dynamic_index.cc b/src/tint/transform/var_for_dynamic_index.cc
index aaebdc7..81af013 100644
--- a/src/tint/transform/var_for_dynamic_index.cc
+++ b/src/tint/transform/var_for_dynamic_index.cc
@@ -13,6 +13,9 @@
// limitations under the License.
#include "src/tint/transform/var_for_dynamic_index.h"
+
+#include <utility>
+
#include "src/tint/program_builder.h"
#include "src/tint/transform/utils/hoist_to_decl_before.h"
@@ -22,7 +25,12 @@
VarForDynamicIndex::~VarForDynamicIndex() = default;
-void VarForDynamicIndex::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+Transform::ApplyResult VarForDynamicIndex::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
HoistToDeclBefore hoist_to_decl_before(ctx);
// Extracts array and matrix values that are dynamically indexed to a
@@ -30,7 +38,7 @@
auto dynamic_index_to_var = [&](const ast::IndexAccessorExpression* access_expr) {
auto* index_expr = access_expr->index;
auto* object_expr = access_expr->object;
- auto& sem = ctx.src->Sem();
+ auto& sem = src->Sem();
if (sem.Get(index_expr)->ConstantValue()) {
// Index expression resolves to a compile time value.
@@ -49,16 +57,21 @@
return hoist_to_decl_before.Add(indexed, object_expr, false, "var_for_index");
};
- for (auto* node : ctx.src->ASTNodes().Objects()) {
+ bool index_accessor_found = false;
+ for (auto* node : src->ASTNodes().Objects()) {
if (auto* access_expr = node->As<ast::IndexAccessorExpression>()) {
if (!dynamic_index_to_var(access_expr)) {
- return;
+ return Program(std::move(b));
}
+ index_accessor_found = true;
}
}
+ if (!index_accessor_found) {
+ return SkipTransform;
+ }
- hoist_to_decl_before.Apply();
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/var_for_dynamic_index.h b/src/tint/transform/var_for_dynamic_index.h
index 39ef2f2..070a2cd 100644
--- a/src/tint/transform/var_for_dynamic_index.h
+++ b/src/tint/transform/var_for_dynamic_index.h
@@ -31,14 +31,10 @@
/// Destructor
~VarForDynamicIndex() override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/vectorize_matrix_conversions.cc b/src/tint/transform/vectorize_matrix_conversions.cc
index 576b885..94fbdf3 100644
--- a/src/tint/transform/vectorize_matrix_conversions.cc
+++ b/src/tint/transform/vectorize_matrix_conversions.cc
@@ -30,11 +30,9 @@
namespace tint::transform {
-VectorizeMatrixConversions::VectorizeMatrixConversions() = default;
+namespace {
-VectorizeMatrixConversions::~VectorizeMatrixConversions() = default;
-
-bool VectorizeMatrixConversions::ShouldRun(const Program* program, const DataMap&) const {
+bool ShouldRun(const Program* program) {
for (auto* node : program->ASTNodes().Objects()) {
if (auto* sem = program->Sem().Get<sem::Expression>(node)) {
if (auto* call = sem->UnwrapMaterialize()->As<sem::Call>()) {
@@ -50,14 +48,29 @@
return false;
}
-void VectorizeMatrixConversions::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+} // namespace
+
+VectorizeMatrixConversions::VectorizeMatrixConversions() = default;
+
+VectorizeMatrixConversions::~VectorizeMatrixConversions() = default;
+
+Transform::ApplyResult VectorizeMatrixConversions::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
+ }
+
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
using HelperFunctionKey =
utils::UnorderedKeyWrapper<std::tuple<const sem::Matrix*, const sem::Matrix*>>;
std::unordered_map<HelperFunctionKey, Symbol> matrix_convs;
ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::CallExpression* {
- auto* call = ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
+ auto* call = src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
auto* ty_conv = call->Target()->As<sem::TypeConversion>();
if (!ty_conv) {
return nullptr;
@@ -72,16 +85,16 @@
return nullptr;
}
- auto& src = args[0];
+ auto& matrix = args[0];
- auto* src_type = args[0]->Type()->UnwrapRef()->As<sem::Matrix>();
+ auto* src_type = matrix->Type()->UnwrapRef()->As<sem::Matrix>();
if (!src_type) {
return nullptr;
}
// The source and destination type of a matrix conversion must have a same shape.
if (!(src_type->rows() == dst_type->rows() && src_type->columns() == dst_type->columns())) {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "source and destination matrix has different shape in matrix conversion";
return nullptr;
}
@@ -90,47 +103,45 @@
utils::Vector<const ast::Expression*, 4> columns;
for (uint32_t c = 0; c < dst_type->columns(); c++) {
auto* src_matrix_expr = src_expression_builder();
- auto* src_column_expr =
- ctx.dst->IndexAccessor(src_matrix_expr, ctx.dst->Expr(tint::AInt(c)));
- columns.Push(ctx.dst->Construct(CreateASTTypeFor(ctx, dst_type->ColumnType()),
- src_column_expr));
+ auto* src_column_expr = b.IndexAccessor(src_matrix_expr, b.Expr(tint::AInt(c)));
+ columns.Push(
+ b.Construct(CreateASTTypeFor(ctx, dst_type->ColumnType()), src_column_expr));
}
- return ctx.dst->Construct(CreateASTTypeFor(ctx, dst_type), columns);
+ return b.Construct(CreateASTTypeFor(ctx, dst_type), columns);
};
// Replace the matrix conversion to column vector conversions and a matrix construction.
- if (!src->HasSideEffects()) {
+ if (!matrix->HasSideEffects()) {
// Simply use the argument's declaration if it has no side effects.
return build_vectorized_conversion_expression([&]() { //
- return ctx.Clone(src->Declaration());
+ return ctx.Clone(matrix->Declaration());
});
} else {
// If has side effects, use a helper function.
auto fn =
utils::GetOrCreate(matrix_convs, HelperFunctionKey{{src_type, dst_type}}, [&] {
- auto name =
- ctx.dst->Symbols().New("convert_mat" + std::to_string(src_type->columns()) +
- "x" + std::to_string(src_type->rows()) + "_" +
- ctx.dst->FriendlyName(src_type->type()) + "_" +
- ctx.dst->FriendlyName(dst_type->type()));
- ctx.dst->Func(
- name,
- utils::Vector{
- ctx.dst->Param("value", CreateASTTypeFor(ctx, src_type)),
- },
- CreateASTTypeFor(ctx, dst_type),
- utils::Vector{
- ctx.dst->Return(build_vectorized_conversion_expression([&]() { //
- return ctx.dst->Expr("value");
- })),
- });
+ auto name = b.Symbols().New(
+ "convert_mat" + std::to_string(src_type->columns()) + "x" +
+ std::to_string(src_type->rows()) + "_" + b.FriendlyName(src_type->type()) +
+ "_" + b.FriendlyName(dst_type->type()));
+ b.Func(name,
+ utils::Vector{
+ b.Param("value", CreateASTTypeFor(ctx, src_type)),
+ },
+ CreateASTTypeFor(ctx, dst_type),
+ utils::Vector{
+ b.Return(build_vectorized_conversion_expression([&]() { //
+ return b.Expr("value");
+ })),
+ });
return name;
});
- return ctx.dst->Call(fn, ctx.Clone(args[0]->Declaration()));
+ return b.Call(fn, ctx.Clone(args[0]->Declaration()));
}
});
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/vectorize_matrix_conversions.h b/src/tint/transform/vectorize_matrix_conversions.h
index f16467c..c86240c 100644
--- a/src/tint/transform/vectorize_matrix_conversions.h
+++ b/src/tint/transform/vectorize_matrix_conversions.h
@@ -28,19 +28,10 @@
/// Destructor
~VectorizeMatrixConversions() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/vectorize_scalar_matrix_initializers.cc b/src/tint/transform/vectorize_scalar_matrix_initializers.cc
index 97b0e4f..e6e1c46 100644
--- a/src/tint/transform/vectorize_scalar_matrix_initializers.cc
+++ b/src/tint/transform/vectorize_scalar_matrix_initializers.cc
@@ -27,12 +27,9 @@
TINT_INSTANTIATE_TYPEINFO(tint::transform::VectorizeScalarMatrixInitializers);
namespace tint::transform {
+namespace {
-VectorizeScalarMatrixInitializers::VectorizeScalarMatrixInitializers() = default;
-
-VectorizeScalarMatrixInitializers::~VectorizeScalarMatrixInitializers() = default;
-
-bool VectorizeScalarMatrixInitializers::ShouldRun(const Program* program, const DataMap&) const {
+bool ShouldRun(const Program* program) {
for (auto* node : program->ASTNodes().Objects()) {
if (auto* call = program->Sem().Get<sem::Call>(node)) {
if (call->Target()->Is<sem::TypeInitializer>() && call->Type()->Is<sem::Matrix>()) {
@@ -46,11 +43,26 @@
return false;
}
-void VectorizeScalarMatrixInitializers::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+} // namespace
+
+VectorizeScalarMatrixInitializers::VectorizeScalarMatrixInitializers() = default;
+
+VectorizeScalarMatrixInitializers::~VectorizeScalarMatrixInitializers() = default;
+
+Transform::ApplyResult VectorizeScalarMatrixInitializers::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
+ }
+
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
std::unordered_map<const sem::Matrix*, Symbol> scalar_inits;
ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::CallExpression* {
- auto* call = ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
+ auto* call = src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
auto* ty_init = call->Target()->As<sem::TypeInitializer>();
if (!ty_init) {
return nullptr;
@@ -87,10 +99,10 @@
}
// Construct the column vector.
- columns.Push(ctx.dst->vec(CreateASTTypeFor(ctx, mat_type->type()), mat_type->rows(),
- std::move(row_values)));
+ columns.Push(b.vec(CreateASTTypeFor(ctx, mat_type->type()), mat_type->rows(),
+ std::move(row_values)));
}
- return ctx.dst->Construct(CreateASTTypeFor(ctx, mat_type), columns);
+ return b.Construct(CreateASTTypeFor(ctx, mat_type), columns);
};
if (args.Length() == 1) {
@@ -98,23 +110,22 @@
// This is done to ensure that the single argument value is only evaluated once, and
// with the correct expression evaluation order.
auto fn = utils::GetOrCreate(scalar_inits, mat_type, [&] {
- auto name =
- ctx.dst->Symbols().New("build_mat" + std::to_string(mat_type->columns()) + "x" +
- std::to_string(mat_type->rows()));
- ctx.dst->Func(name,
- utils::Vector{
- // Single scalar parameter
- ctx.dst->Param("value", CreateASTTypeFor(ctx, mat_type->type())),
- },
- CreateASTTypeFor(ctx, mat_type),
- utils::Vector{
- ctx.dst->Return(build_mat([&](uint32_t, uint32_t) { //
- return ctx.dst->Expr("value");
- })),
- });
+ auto name = b.Symbols().New("build_mat" + std::to_string(mat_type->columns()) +
+ "x" + std::to_string(mat_type->rows()));
+ b.Func(name,
+ utils::Vector{
+ // Single scalar parameter
+ b.Param("value", CreateASTTypeFor(ctx, mat_type->type())),
+ },
+ CreateASTTypeFor(ctx, mat_type),
+ utils::Vector{
+ b.Return(build_mat([&](uint32_t, uint32_t) { //
+ return b.Expr("value");
+ })),
+ });
return name;
});
- return ctx.dst->Call(fn, ctx.Clone(args[0]->Declaration()));
+ return b.Call(fn, ctx.Clone(args[0]->Declaration()));
}
if (args.Length() == mat_type->columns() * mat_type->rows()) {
@@ -123,12 +134,13 @@
});
}
- TINT_ICE(Transform, ctx.dst->Diagnostics())
+ TINT_ICE(Transform, b.Diagnostics())
<< "matrix initializer has unexpected number of arguments";
return nullptr;
});
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/vectorize_scalar_matrix_initializers.h b/src/tint/transform/vectorize_scalar_matrix_initializers.h
index 342754a..f9c0164 100644
--- a/src/tint/transform/vectorize_scalar_matrix_initializers.h
+++ b/src/tint/transform/vectorize_scalar_matrix_initializers.h
@@ -29,19 +29,10 @@
/// Destructor
~VectorizeScalarMatrixInitializers() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/vertex_pulling.cc b/src/tint/transform/vertex_pulling.cc
index 00b5a06..d5ee424 100644
--- a/src/tint/transform/vertex_pulling.cc
+++ b/src/tint/transform/vertex_pulling.cc
@@ -201,13 +201,46 @@
return {BaseType::kInvalid, 0};
}
-struct State {
- State(CloneContext& context, const VertexPulling::Config& c) : ctx(context), cfg(c) {}
- State(const State&) = default;
- ~State() = default;
+} // namespace
- /// LocationReplacement describes an ast::Variable replacement for a
- /// location input.
+/// PIMPL state for the transform
+struct VertexPulling::State {
+ /// Constructor
+ /// @param program the source program
+ /// @param c the VertexPulling config
+ State(const Program* program, const VertexPulling::Config& c) : src(program), cfg(c) {}
+
+ /// Runs the transform
+ /// @returns the new program or SkipTransform if the transform is not required
+ ApplyResult Run() {
+ // Find entry point
+ const ast::Function* func = nullptr;
+ for (auto* fn : src->AST().Functions()) {
+ if (fn->PipelineStage() == ast::PipelineStage::kVertex) {
+ if (func != nullptr) {
+ b.Diagnostics().add_error(
+ diag::System::Transform,
+ "VertexPulling found more than one vertex entry point");
+ return Program(std::move(b));
+ }
+ func = fn;
+ }
+ }
+ if (func == nullptr) {
+ b.Diagnostics().add_error(diag::System::Transform,
+ "Vertex stage entry point not found");
+ return Program(std::move(b));
+ }
+
+ AddVertexStorageBuffers();
+ Process(func);
+
+ ctx.Clone();
+ return Program(std::move(b));
+ }
+
+ private:
+ /// LocationReplacement describes an ast::Variable replacement for a location input.
struct LocationReplacement {
/// The variable to replace in the source Program
ast::Variable* from;
@@ -215,13 +248,22 @@
ast::Variable* to;
};
+ /// LocationInfo describes an input location
struct LocationInfo {
+ /// A builder that builds the expression that resolves to the (transformed) input location
std::function<const ast::Expression*()> expr;
+ /// The store type of the location variable
const sem::Type* type;
};
- CloneContext& ctx;
+ /// The source program
+ const Program* const src;
+ /// The transform config
VertexPulling::Config const cfg;
+ /// The target program builder
+ ProgramBuilder b;
+ /// The clone context
+ CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
std::unordered_map<uint32_t, LocationInfo> location_info;
std::function<const ast::Expression*()> vertex_index_expr = nullptr;
std::function<const ast::Expression*()> instance_index_expr = nullptr;
@@ -235,7 +277,7 @@
Symbol GetVertexBufferName(uint32_t index) {
return utils::GetOrCreate(vertex_buffer_names, index, [&] {
static const char kVertexBufferNamePrefix[] = "tint_pulling_vertex_buffer_";
- return ctx.dst->Symbols().New(kVertexBufferNamePrefix + std::to_string(index));
+ return b.Symbols().New(kVertexBufferNamePrefix + std::to_string(index));
});
}
@@ -243,7 +285,7 @@
Symbol GetStructBufferName() {
if (!struct_buffer_name.IsValid()) {
static const char kStructBufferName[] = "tint_vertex_data";
- struct_buffer_name = ctx.dst->Symbols().New(kStructBufferName);
+ struct_buffer_name = b.Symbols().New(kStructBufferName);
}
return struct_buffer_name;
}
@@ -252,21 +294,19 @@
void AddVertexStorageBuffers() {
// Creating the struct type
static const char kStructName[] = "TintVertexData";
- auto* struct_type =
- ctx.dst->Structure(ctx.dst->Symbols().New(kStructName),
- utils::Vector{
- ctx.dst->Member(GetStructBufferName(), ctx.dst->ty.array<u32>()),
- });
+ auto* struct_type = b.Structure(b.Symbols().New(kStructName),
+ utils::Vector{
+ b.Member(GetStructBufferName(), b.ty.array<u32>()),
+ });
for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
// The decorated variable with struct type
- ctx.dst->GlobalVar(GetVertexBufferName(i), ctx.dst->ty.Of(struct_type),
- ast::AddressSpace::kStorage, ast::Access::kRead,
- ctx.dst->Binding(AInt(i)), ctx.dst->Group(AInt(cfg.pulling_group)));
+ b.GlobalVar(GetVertexBufferName(i), b.ty.Of(struct_type), ast::AddressSpace::kStorage,
+ ast::Access::kRead, b.Binding(AInt(i)), b.Group(AInt(cfg.pulling_group)));
}
}
/// Creates and returns the assignment to the variables from the buffers
- ast::BlockStatement* CreateVertexPullingPreamble() {
+ const ast::BlockStatement* CreateVertexPullingPreamble() {
// Assign by looking at the vertex descriptor to find attributes with
// matching location.
@@ -276,7 +316,7 @@
const VertexBufferLayoutDescriptor& buffer_layout = cfg.vertex_state[buffer_idx];
if ((buffer_layout.array_stride & 3) != 0) {
- ctx.dst->Diagnostics().add_error(
+ b.Diagnostics().add_error(
diag::System::Transform,
"WebGPU requires that vertex stride must be a multiple of 4 bytes, "
"but VertexPulling array stride for buffer " +
@@ -292,15 +332,15 @@
// buffer_array_base is the base array offset for all the vertex
// attributes. These are units of uint (4 bytes).
auto buffer_array_base =
- ctx.dst->Symbols().New("buffer_array_base_" + std::to_string(buffer_idx));
+ b.Symbols().New("buffer_array_base_" + std::to_string(buffer_idx));
auto* attribute_offset = index_expr;
if (buffer_layout.array_stride != 4) {
- attribute_offset = ctx.dst->Mul(index_expr, u32(buffer_layout.array_stride / 4u));
+ attribute_offset = b.Mul(index_expr, u32(buffer_layout.array_stride / 4u));
}
// let pulling_offset_n = <attribute_offset>
- stmts.Push(ctx.dst->Decl(ctx.dst->Let(buffer_array_base, attribute_offset)));
+ stmts.Push(b.Decl(b.Let(buffer_array_base, attribute_offset)));
for (const VertexAttributeDescriptor& attribute_desc : buffer_layout.attributes) {
auto it = location_info.find(attribute_desc.shader_location);
@@ -320,8 +360,8 @@
err << "VertexAttributeDescriptor for location "
<< std::to_string(attribute_desc.shader_location) << " has format "
<< attribute_desc.format << " but shader expects "
- << var.type->FriendlyName(ctx.src->Symbols());
- ctx.dst->Diagnostics().add_error(diag::System::Transform, err.str());
+ << var.type->FriendlyName(src->Symbols());
+ b.Diagnostics().add_error(diag::System::Transform, err.str());
return nullptr;
}
@@ -337,16 +377,16 @@
// WGSL variable vector width is smaller than the loaded vector width
switch (var_dt.width) {
case 1:
- value = ctx.dst->MemberAccessor(fetch, "x");
+ value = b.MemberAccessor(fetch, "x");
break;
case 2:
- value = ctx.dst->MemberAccessor(fetch, "xy");
+ value = b.MemberAccessor(fetch, "xy");
break;
case 3:
- value = ctx.dst->MemberAccessor(fetch, "xyz");
+ value = b.MemberAccessor(fetch, "xyz");
break;
default:
- TINT_UNREACHABLE(Transform, ctx.dst->Diagnostics()) << var_dt.width;
+ TINT_UNREACHABLE(Transform, b.Diagnostics()) << var_dt.width;
return nullptr;
}
} else if (var_dt.width > fmt_dt.width) {
@@ -355,32 +395,32 @@
utils::Vector<const ast::Expression*, 8> values{fetch};
switch (var_dt.base_type) {
case BaseType::kI32:
- ty = ctx.dst->ty.i32();
+ ty = b.ty.i32();
for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
- values.Push(ctx.dst->Expr((i == 3) ? 1_i : 0_i));
+ values.Push(b.Expr((i == 3) ? 1_i : 0_i));
}
break;
case BaseType::kU32:
- ty = ctx.dst->ty.u32();
+ ty = b.ty.u32();
for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
- values.Push(ctx.dst->Expr((i == 3) ? 1_u : 0_u));
+ values.Push(b.Expr((i == 3) ? 1_u : 0_u));
}
break;
case BaseType::kF32:
- ty = ctx.dst->ty.f32();
+ ty = b.ty.f32();
for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
- values.Push(ctx.dst->Expr((i == 3) ? 1_f : 0_f));
+ values.Push(b.Expr((i == 3) ? 1_f : 0_f));
}
break;
default:
- TINT_UNREACHABLE(Transform, ctx.dst->Diagnostics()) << var_dt.base_type;
+ TINT_UNREACHABLE(Transform, b.Diagnostics()) << var_dt.base_type;
return nullptr;
}
- value = ctx.dst->Construct(ctx.dst->ty.vec(ty, var_dt.width), values);
+ value = b.Construct(b.ty.vec(ty, var_dt.width), values);
}
// Assign the value to the WGSL variable
- stmts.Push(ctx.dst->Assign(var.expr(), value));
+ stmts.Push(b.Assign(var.expr(), value));
}
}
@@ -388,7 +428,7 @@
return nullptr;
}
- return ctx.dst->create<ast::BlockStatement>(std::move(stmts));
+ return b.Block(std::move(stmts));
}
/// Generates an expression reading from a buffer a specific format.
@@ -407,7 +447,7 @@
};
// Returns a i32 loaded from buffer_base + offset.
- auto load_i32 = [&] { return ctx.dst->Bitcast<i32>(load_u32()); };
+ auto load_i32 = [&] { return b.Bitcast<i32>(load_u32()); };
// Returns a u32 loaded from buffer_base + offset + 4.
auto load_next_u32 = [&] {
@@ -415,7 +455,7 @@
};
// Returns a i32 loaded from buffer_base + offset + 4.
- auto load_next_i32 = [&] { return ctx.dst->Bitcast<i32>(load_next_u32()); };
+ auto load_next_i32 = [&] { return b.Bitcast<i32>(load_next_u32()); };
// Returns a u16 loaded from offset, packed in the high 16 bits of a u32.
// The low 16 bits are 0.
@@ -427,17 +467,17 @@
LoadPrimitive(array_base, low_u32_offset, buffer, VertexFormat::kUint32);
switch (offset & 3) {
case 0:
- return ctx.dst->Shl(low_u32, 16_u);
+ return b.Shl(low_u32, 16_u);
case 1:
- return ctx.dst->And(ctx.dst->Shl(low_u32, 8_u), 0xffff0000_u);
+ return b.And(b.Shl(low_u32, 8_u), 0xffff0000_u);
case 2:
- return ctx.dst->And(low_u32, 0xffff0000_u);
+ return b.And(low_u32, 0xffff0000_u);
default: { // 3:
auto* high_u32 = LoadPrimitive(array_base, low_u32_offset + 4, buffer,
VertexFormat::kUint32);
- auto* shr = ctx.dst->Shr(low_u32, 8_u);
- auto* shl = ctx.dst->Shl(high_u32, 24_u);
- return ctx.dst->And(ctx.dst->Or(shl, shr), 0xffff0000_u);
+ auto* shr = b.Shr(low_u32, 8_u);
+ auto* shl = b.Shl(high_u32, 24_u);
+ return b.And(b.Or(shl, shr), 0xffff0000_u);
}
}
};
@@ -450,24 +490,24 @@
LoadPrimitive(array_base, low_u32_offset, buffer, VertexFormat::kUint32);
switch (offset & 3) {
case 0:
- return ctx.dst->And(low_u32, 0xffff_u);
+ return b.And(low_u32, 0xffff_u);
case 1:
- return ctx.dst->And(ctx.dst->Shr(low_u32, 8_u), 0xffff_u);
+ return b.And(b.Shr(low_u32, 8_u), 0xffff_u);
case 2:
- return ctx.dst->Shr(low_u32, 16_u);
+ return b.Shr(low_u32, 16_u);
default: { // 3:
auto* high_u32 = LoadPrimitive(array_base, low_u32_offset + 4, buffer,
VertexFormat::kUint32);
- auto* shr = ctx.dst->Shr(low_u32, 24_u);
- auto* shl = ctx.dst->Shl(high_u32, 8_u);
- return ctx.dst->And(ctx.dst->Or(shl, shr), 0xffff_u);
+ auto* shr = b.Shr(low_u32, 24_u);
+ auto* shl = b.Shl(high_u32, 8_u);
+ return b.And(b.Or(shl, shr), 0xffff_u);
}
}
};
// Returns a i16 loaded from offset, packed in the high 16 bits of a u32.
// The low 16 bits are 0.
- auto load_i16_h = [&] { return ctx.dst->Bitcast<i32>(load_u16_h()); };
+ auto load_i16_h = [&] { return b.Bitcast<i32>(load_u16_h()); };
// Assumptions are made that alignment must be at least as large as the size
// of a single component.
@@ -480,128 +520,121 @@
// Vectors of basic primitives
case VertexFormat::kUint32x2:
- return LoadVec(array_base, offset, buffer, 4, ctx.dst->ty.u32(),
- VertexFormat::kUint32, 2);
+ return LoadVec(array_base, offset, buffer, 4, b.ty.u32(), VertexFormat::kUint32, 2);
case VertexFormat::kUint32x3:
- return LoadVec(array_base, offset, buffer, 4, ctx.dst->ty.u32(),
- VertexFormat::kUint32, 3);
+ return LoadVec(array_base, offset, buffer, 4, b.ty.u32(), VertexFormat::kUint32, 3);
case VertexFormat::kUint32x4:
- return LoadVec(array_base, offset, buffer, 4, ctx.dst->ty.u32(),
- VertexFormat::kUint32, 4);
+ return LoadVec(array_base, offset, buffer, 4, b.ty.u32(), VertexFormat::kUint32, 4);
case VertexFormat::kSint32x2:
- return LoadVec(array_base, offset, buffer, 4, ctx.dst->ty.i32(),
- VertexFormat::kSint32, 2);
+ return LoadVec(array_base, offset, buffer, 4, b.ty.i32(), VertexFormat::kSint32, 2);
case VertexFormat::kSint32x3:
- return LoadVec(array_base, offset, buffer, 4, ctx.dst->ty.i32(),
- VertexFormat::kSint32, 3);
+ return LoadVec(array_base, offset, buffer, 4, b.ty.i32(), VertexFormat::kSint32, 3);
case VertexFormat::kSint32x4:
- return LoadVec(array_base, offset, buffer, 4, ctx.dst->ty.i32(),
- VertexFormat::kSint32, 4);
+ return LoadVec(array_base, offset, buffer, 4, b.ty.i32(), VertexFormat::kSint32, 4);
case VertexFormat::kFloat32x2:
- return LoadVec(array_base, offset, buffer, 4, ctx.dst->ty.f32(),
- VertexFormat::kFloat32, 2);
+ return LoadVec(array_base, offset, buffer, 4, b.ty.f32(), VertexFormat::kFloat32,
+ 2);
case VertexFormat::kFloat32x3:
- return LoadVec(array_base, offset, buffer, 4, ctx.dst->ty.f32(),
- VertexFormat::kFloat32, 3);
+ return LoadVec(array_base, offset, buffer, 4, b.ty.f32(), VertexFormat::kFloat32,
+ 3);
case VertexFormat::kFloat32x4:
- return LoadVec(array_base, offset, buffer, 4, ctx.dst->ty.f32(),
- VertexFormat::kFloat32, 4);
+ return LoadVec(array_base, offset, buffer, 4, b.ty.f32(), VertexFormat::kFloat32,
+ 4);
case VertexFormat::kUint8x2: {
// yyxx0000, yyxx0000
- auto* u16s = ctx.dst->vec2<u32>(load_u16_h());
+ auto* u16s = b.vec2<u32>(load_u16_h());
// xx000000, yyxx0000
- auto* shl = ctx.dst->Shl(u16s, ctx.dst->vec2<u32>(8_u, 0_u));
+ auto* shl = b.Shl(u16s, b.vec2<u32>(8_u, 0_u));
// 000000xx, 000000yy
- return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(24_u));
+ return b.Shr(shl, b.vec2<u32>(24_u));
}
case VertexFormat::kUint8x4: {
// wwzzyyxx, wwzzyyxx, wwzzyyxx, wwzzyyxx
- auto* u32s = ctx.dst->vec4<u32>(load_u32());
+ auto* u32s = b.vec4<u32>(load_u32());
// xx000000, yyxx0000, zzyyxx00, wwzzyyxx
- auto* shl = ctx.dst->Shl(u32s, ctx.dst->vec4<u32>(24_u, 16_u, 8_u, 0_u));
+ auto* shl = b.Shl(u32s, b.vec4<u32>(24_u, 16_u, 8_u, 0_u));
// 000000xx, 000000yy, 000000zz, 000000ww
- return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(24_u));
+ return b.Shr(shl, b.vec4<u32>(24_u));
}
case VertexFormat::kUint16x2: {
// yyyyxxxx, yyyyxxxx
- auto* u32s = ctx.dst->vec2<u32>(load_u32());
+ auto* u32s = b.vec2<u32>(load_u32());
// xxxx0000, yyyyxxxx
- auto* shl = ctx.dst->Shl(u32s, ctx.dst->vec2<u32>(16_u, 0_u));
+ auto* shl = b.Shl(u32s, b.vec2<u32>(16_u, 0_u));
// 0000xxxx, 0000yyyy
- return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(16_u));
+ return b.Shr(shl, b.vec2<u32>(16_u));
}
case VertexFormat::kUint16x4: {
// yyyyxxxx, wwwwzzzz
- auto* u32s = ctx.dst->vec2<u32>(load_u32(), load_next_u32());
+ auto* u32s = b.vec2<u32>(load_u32(), load_next_u32());
// yyyyxxxx, yyyyxxxx, wwwwzzzz, wwwwzzzz
- auto* xxyy = ctx.dst->MemberAccessor(u32s, "xxyy");
+ auto* xxyy = b.MemberAccessor(u32s, "xxyy");
// xxxx0000, yyyyxxxx, zzzz0000, wwwwzzzz
- auto* shl = ctx.dst->Shl(xxyy, ctx.dst->vec4<u32>(16_u, 0_u, 16_u, 0_u));
+ auto* shl = b.Shl(xxyy, b.vec4<u32>(16_u, 0_u, 16_u, 0_u));
// 0000xxxx, 0000yyyy, 0000zzzz, 0000wwww
- return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(16_u));
+ return b.Shr(shl, b.vec4<u32>(16_u));
}
case VertexFormat::kSint8x2: {
// yyxx0000, yyxx0000
- auto* i16s = ctx.dst->vec2<i32>(load_i16_h());
+ auto* i16s = b.vec2<i32>(load_i16_h());
// xx000000, yyxx0000
- auto* shl = ctx.dst->Shl(i16s, ctx.dst->vec2<u32>(8_u, 0_u));
+ auto* shl = b.Shl(i16s, b.vec2<u32>(8_u, 0_u));
// ssssssxx, ssssssyy
- return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(24_u));
+ return b.Shr(shl, b.vec2<u32>(24_u));
}
case VertexFormat::kSint8x4: {
// wwzzyyxx, wwzzyyxx, wwzzyyxx, wwzzyyxx
- auto* i32s = ctx.dst->vec4<i32>(load_i32());
+ auto* i32s = b.vec4<i32>(load_i32());
// xx000000, yyxx0000, zzyyxx00, wwzzyyxx
- auto* shl = ctx.dst->Shl(i32s, ctx.dst->vec4<u32>(24_u, 16_u, 8_u, 0_u));
+ auto* shl = b.Shl(i32s, b.vec4<u32>(24_u, 16_u, 8_u, 0_u));
// ssssssxx, ssssssyy, sssssszz, ssssssww
- return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(24_u));
+ return b.Shr(shl, b.vec4<u32>(24_u));
}
case VertexFormat::kSint16x2: {
// yyyyxxxx, yyyyxxxx
- auto* i32s = ctx.dst->vec2<i32>(load_i32());
+ auto* i32s = b.vec2<i32>(load_i32());
// xxxx0000, yyyyxxxx
- auto* shl = ctx.dst->Shl(i32s, ctx.dst->vec2<u32>(16_u, 0_u));
+ auto* shl = b.Shl(i32s, b.vec2<u32>(16_u, 0_u));
// ssssxxxx, ssssyyyy
- return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(16_u));
+ return b.Shr(shl, b.vec2<u32>(16_u));
}
case VertexFormat::kSint16x4: {
// yyyyxxxx, wwwwzzzz
- auto* i32s = ctx.dst->vec2<i32>(load_i32(), load_next_i32());
+ auto* i32s = b.vec2<i32>(load_i32(), load_next_i32());
// yyyyxxxx, yyyyxxxx, wwwwzzzz, wwwwzzzz
- auto* xxyy = ctx.dst->MemberAccessor(i32s, "xxyy");
+ auto* xxyy = b.MemberAccessor(i32s, "xxyy");
// xxxx0000, yyyyxxxx, zzzz0000, wwwwzzzz
- auto* shl = ctx.dst->Shl(xxyy, ctx.dst->vec4<u32>(16_u, 0_u, 16_u, 0_u));
+ auto* shl = b.Shl(xxyy, b.vec4<u32>(16_u, 0_u, 16_u, 0_u));
// ssssxxxx, ssssyyyy, sssszzzz, sssswwww
- return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(16_u));
+ return b.Shr(shl, b.vec4<u32>(16_u));
}
case VertexFormat::kUnorm8x2:
- return ctx.dst->MemberAccessor(ctx.dst->Call("unpack4x8unorm", load_u16_l()), "xy");
+ return b.MemberAccessor(b.Call("unpack4x8unorm", load_u16_l()), "xy");
case VertexFormat::kSnorm8x2:
- return ctx.dst->MemberAccessor(ctx.dst->Call("unpack4x8snorm", load_u16_l()), "xy");
+ return b.MemberAccessor(b.Call("unpack4x8snorm", load_u16_l()), "xy");
case VertexFormat::kUnorm8x4:
- return ctx.dst->Call("unpack4x8unorm", load_u32());
+ return b.Call("unpack4x8unorm", load_u32());
case VertexFormat::kSnorm8x4:
- return ctx.dst->Call("unpack4x8snorm", load_u32());
+ return b.Call("unpack4x8snorm", load_u32());
case VertexFormat::kUnorm16x2:
- return ctx.dst->Call("unpack2x16unorm", load_u32());
+ return b.Call("unpack2x16unorm", load_u32());
case VertexFormat::kSnorm16x2:
- return ctx.dst->Call("unpack2x16snorm", load_u32());
+ return b.Call("unpack2x16snorm", load_u32());
case VertexFormat::kFloat16x2:
- return ctx.dst->Call("unpack2x16float", load_u32());
+ return b.Call("unpack2x16float", load_u32());
case VertexFormat::kUnorm16x4:
- return ctx.dst->vec4<f32>(ctx.dst->Call("unpack2x16unorm", load_u32()),
- ctx.dst->Call("unpack2x16unorm", load_next_u32()));
+ return b.vec4<f32>(b.Call("unpack2x16unorm", load_u32()),
+ b.Call("unpack2x16unorm", load_next_u32()));
case VertexFormat::kSnorm16x4:
- return ctx.dst->vec4<f32>(ctx.dst->Call("unpack2x16snorm", load_u32()),
- ctx.dst->Call("unpack2x16snorm", load_next_u32()));
+ return b.vec4<f32>(b.Call("unpack2x16snorm", load_u32()),
+ b.Call("unpack2x16snorm", load_next_u32()));
case VertexFormat::kFloat16x4:
- return ctx.dst->vec4<f32>(ctx.dst->Call("unpack2x16float", load_u32()),
- ctx.dst->Call("unpack2x16float", load_next_u32()));
+ return b.vec4<f32>(b.Call("unpack2x16float", load_u32()),
+ b.Call("unpack2x16float", load_next_u32()));
}
- TINT_UNREACHABLE(Transform, ctx.dst->Diagnostics())
- << "format " << static_cast<int>(format);
+ TINT_UNREACHABLE(Transform, b.Diagnostics()) << "format " << static_cast<int>(format);
return nullptr;
}
@@ -623,12 +656,12 @@
const ast ::Expression* index = nullptr;
if (offset > 0) {
- index = ctx.dst->Add(array_base, u32(offset / 4));
+ index = b.Add(array_base, u32(offset / 4));
} else {
- index = ctx.dst->Expr(array_base);
+ index = b.Expr(array_base);
}
- u = ctx.dst->IndexAccessor(
- ctx.dst->MemberAccessor(GetVertexBufferName(buffer), GetStructBufferName()), index);
+ u = b.IndexAccessor(
+ b.MemberAccessor(GetVertexBufferName(buffer), GetStructBufferName()), index);
} else {
// Unaligned load
@@ -639,22 +672,22 @@
uint32_t shift = 8u * (offset & 3u);
- auto* low_shr = ctx.dst->Shr(low, u32(shift));
- auto* high_shl = ctx.dst->Shl(high, u32(32u - shift));
- u = ctx.dst->Or(low_shr, high_shl);
+ auto* low_shr = b.Shr(low, u32(shift));
+ auto* high_shl = b.Shl(high, u32(32u - shift));
+ u = b.Or(low_shr, high_shl);
}
switch (format) {
case VertexFormat::kUint32:
return u;
case VertexFormat::kSint32:
- return ctx.dst->Bitcast(ctx.dst->ty.i32(), u);
+ return b.Bitcast(b.ty.i32(), u);
case VertexFormat::kFloat32:
- return ctx.dst->Bitcast(ctx.dst->ty.f32(), u);
+ return b.Bitcast(b.ty.f32(), u);
default:
break;
}
- TINT_UNREACHABLE(Transform, ctx.dst->Diagnostics())
+ TINT_UNREACHABLE(Transform, b.Diagnostics())
<< "invalid format for LoadPrimitive" << static_cast<int>(format);
return nullptr;
}
@@ -682,8 +715,7 @@
expr_list.Push(LoadPrimitive(array_base, primitive_offset, buffer, base_format));
}
- return ctx.dst->Construct(ctx.dst->create<ast::Vector>(base_type, count),
- std::move(expr_list));
+ return b.Construct(b.create<ast::Vector>(base_type, count), std::move(expr_list));
}
/// Process a non-struct entry point parameter.
@@ -696,34 +728,30 @@
// Create a function-scope variable to replace the parameter.
auto func_var_sym = ctx.Clone(param->symbol);
auto* func_var_type = ctx.Clone(param->type);
- auto* func_var = ctx.dst->Var(func_var_sym, func_var_type);
- ctx.InsertFront(func->body->statements, ctx.dst->Decl(func_var));
+ auto* func_var = b.Var(func_var_sym, func_var_type);
+ ctx.InsertFront(func->body->statements, b.Decl(func_var));
// Capture mapping from location to the new variable.
LocationInfo info;
- info.expr = [this, func_var]() { return ctx.dst->Expr(func_var); };
+ info.expr = [this, func_var]() { return b.Expr(func_var); };
- auto* sem = ctx.src->Sem().Get<sem::Parameter>(param);
+ auto* sem = src->Sem().Get<sem::Parameter>(param);
info.type = sem->Type();
if (!sem->Location().has_value()) {
- TINT_ICE(Transform, ctx.dst->Diagnostics()) << "Location missing value";
+ TINT_ICE(Transform, b.Diagnostics()) << "Location missing value";
return;
}
location_info[sem->Location().value()] = info;
} else if (auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(param->attributes)) {
// Check for existing vertex_index and instance_index builtins.
if (builtin->builtin == ast::BuiltinValue::kVertexIndex) {
- vertex_index_expr = [this, param]() {
- return ctx.dst->Expr(ctx.Clone(param->symbol));
- };
+ vertex_index_expr = [this, param]() { return b.Expr(ctx.Clone(param->symbol)); };
} else if (builtin->builtin == ast::BuiltinValue::kInstanceIndex) {
- instance_index_expr = [this, param]() {
- return ctx.dst->Expr(ctx.Clone(param->symbol));
- };
+ instance_index_expr = [this, param]() { return b.Expr(ctx.Clone(param->symbol)); };
}
new_function_parameters.Push(ctx.Clone(param));
} else {
- TINT_ICE(Transform, ctx.dst->Diagnostics()) << "Invalid entry point parameter";
+ TINT_ICE(Transform, b.Diagnostics()) << "Invalid entry point parameter";
}
}
@@ -746,7 +774,7 @@
for (auto* member : struct_ty->members) {
auto member_sym = ctx.Clone(member->symbol);
std::function<const ast::Expression*()> member_expr = [this, param_sym, member_sym]() {
- return ctx.dst->MemberAccessor(param_sym, member_sym);
+ return b.MemberAccessor(param_sym, member_sym);
};
if (ast::HasAttribute<ast::LocationAttribute>(member->attributes)) {
@@ -754,7 +782,7 @@
LocationInfo info;
info.expr = member_expr;
- auto* sem = ctx.src->Sem().Get(member);
+ auto* sem = src->Sem().Get(member);
info.type = sem->Type();
TINT_ASSERT(Transform, sem->Location().has_value());
@@ -770,7 +798,7 @@
}
members_to_clone.Push(member);
} else {
- TINT_ICE(Transform, ctx.dst->Diagnostics()) << "Invalid entry point parameter";
+ TINT_ICE(Transform, b.Diagnostics()) << "Invalid entry point parameter";
}
}
@@ -781,8 +809,8 @@
}
// Create a function-scope variable to replace the parameter.
- auto* func_var = ctx.dst->Var(param_sym, ctx.Clone(param->type));
- ctx.InsertFront(func->body->statements, ctx.dst->Decl(func_var));
+ auto* func_var = b.Var(param_sym, ctx.Clone(param->type));
+ ctx.InsertFront(func->body->statements, b.Decl(func_var));
if (!members_to_clone.IsEmpty()) {
// Create a new struct without the location attributes.
@@ -791,20 +819,20 @@
auto member_sym = ctx.Clone(member->symbol);
auto* member_type = ctx.Clone(member->type);
auto member_attrs = ctx.Clone(member->attributes);
- new_members.Push(ctx.dst->Member(member_sym, member_type, std::move(member_attrs)));
+ new_members.Push(b.Member(member_sym, member_type, std::move(member_attrs)));
}
- auto* new_struct = ctx.dst->Structure(ctx.dst->Sym(), new_members);
+ auto* new_struct = b.Structure(b.Sym(), new_members);
// Create a new function parameter with this struct.
- auto* new_param = ctx.dst->Param(ctx.dst->Sym(), ctx.dst->ty.Of(new_struct));
+ auto* new_param = b.Param(b.Sym(), b.ty.Of(new_struct));
new_function_parameters.Push(new_param);
// Copy values from the new parameter to the function-scope variable.
for (auto* member : members_to_clone) {
auto member_name = ctx.Clone(member->symbol);
ctx.InsertFront(func->body->statements,
- ctx.dst->Assign(ctx.dst->MemberAccessor(func_var, member_name),
- ctx.dst->MemberAccessor(new_param, member_name)));
+ b.Assign(b.MemberAccessor(func_var, member_name),
+ b.MemberAccessor(new_param, member_name)));
}
}
}
@@ -818,7 +846,7 @@
// Process entry point parameters.
for (auto* param : func->params) {
- auto* sem = ctx.src->Sem().Get(param);
+ auto* sem = src->Sem().Get(param);
if (auto* str = sem->Type()->As<sem::Struct>()) {
ProcessStructParameter(func, param, str->Declaration());
} else {
@@ -830,11 +858,11 @@
if (!vertex_index_expr) {
for (const VertexBufferLayoutDescriptor& layout : cfg.vertex_state) {
if (layout.step_mode == VertexStepMode::kVertex) {
- auto name = ctx.dst->Symbols().New("tint_pulling_vertex_index");
- new_function_parameters.Push(ctx.dst->Param(
- name, ctx.dst->ty.u32(),
- utils::Vector{ctx.dst->Builtin(ast::BuiltinValue::kVertexIndex)}));
- vertex_index_expr = [this, name]() { return ctx.dst->Expr(name); };
+ auto name = b.Symbols().New("tint_pulling_vertex_index");
+ new_function_parameters.Push(
+ b.Param(name, b.ty.u32(),
+ utils::Vector{b.Builtin(ast::BuiltinValue::kVertexIndex)}));
+ vertex_index_expr = [this, name]() { return b.Expr(name); };
break;
}
}
@@ -842,11 +870,11 @@
if (!instance_index_expr) {
for (const VertexBufferLayoutDescriptor& layout : cfg.vertex_state) {
if (layout.step_mode == VertexStepMode::kInstance) {
- auto name = ctx.dst->Symbols().New("tint_pulling_instance_index");
- new_function_parameters.Push(ctx.dst->Param(
- name, ctx.dst->ty.u32(),
- utils::Vector{ctx.dst->Builtin(ast::BuiltinValue::kInstanceIndex)}));
- instance_index_expr = [this, name]() { return ctx.dst->Expr(name); };
+ auto name = b.Symbols().New("tint_pulling_instance_index");
+ new_function_parameters.Push(
+ b.Param(name, b.ty.u32(),
+ utils::Vector{b.Builtin(ast::BuiltinValue::kInstanceIndex)}));
+ instance_index_expr = [this, name]() { return b.Expr(name); };
break;
}
}
@@ -864,53 +892,24 @@
auto attrs = ctx.Clone(func->attributes);
auto ret_attrs = ctx.Clone(func->return_type_attributes);
auto* new_func =
- ctx.dst->create<ast::Function>(func->source, func_sym, new_function_parameters,
- ret_type, body, std::move(attrs), std::move(ret_attrs));
+ b.create<ast::Function>(func->source, func_sym, new_function_parameters, ret_type, body,
+ std::move(attrs), std::move(ret_attrs));
ctx.Replace(func, new_func);
}
};
-} // namespace
-
VertexPulling::VertexPulling() = default;
VertexPulling::~VertexPulling() = default;
-void VertexPulling::Run(CloneContext& ctx, const DataMap& inputs, DataMap&) const {
+Transform::ApplyResult VertexPulling::Apply(const Program* src,
+ const DataMap& inputs,
+ DataMap&) const {
auto cfg = cfg_;
if (auto* cfg_data = inputs.Get<Config>()) {
cfg = *cfg_data;
}
- // Find entry point
- const ast::Function* func = nullptr;
- for (auto* fn : ctx.src->AST().Functions()) {
- if (fn->PipelineStage() == ast::PipelineStage::kVertex) {
- if (func != nullptr) {
- ctx.dst->Diagnostics().add_error(
- diag::System::Transform,
- "VertexPulling found more than one vertex entry point");
- return;
- }
- func = fn;
- }
- }
- if (func == nullptr) {
- ctx.dst->Diagnostics().add_error(diag::System::Transform,
- "Vertex stage entry point not found");
- return;
- }
-
- // TODO(idanr): Need to check shader locations in descriptor cover all
- // attributes
-
- // TODO(idanr): Make sure we covered all error cases, to guarantee the
- // following stages will pass
-
- State state{ctx, cfg};
- state.AddVertexStorageBuffers();
- state.Process(func);
-
- ctx.Clone();
+ return State{src, cfg}.Run();
}
VertexPulling::Config::Config() = default;
diff --git a/src/tint/transform/vertex_pulling.h b/src/tint/transform/vertex_pulling.h
index 6dd35bc..c0f88a5 100644
--- a/src/tint/transform/vertex_pulling.h
+++ b/src/tint/transform/vertex_pulling.h
@@ -171,16 +171,14 @@
/// Destructor
~VertexPulling() override;
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
private:
+ struct State;
+
Config cfg_;
};
diff --git a/src/tint/transform/while_to_loop.cc b/src/tint/transform/while_to_loop.cc
index 45944e6..d359d2e 100644
--- a/src/tint/transform/while_to_loop.cc
+++ b/src/tint/transform/while_to_loop.cc
@@ -14,18 +14,17 @@
#include "src/tint/transform/while_to_loop.h"
+#include <utility>
+
#include "src/tint/ast/break_statement.h"
#include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::transform::WhileToLoop);
namespace tint::transform {
+namespace {
-WhileToLoop::WhileToLoop() = default;
-
-WhileToLoop::~WhileToLoop() = default;
-
-bool WhileToLoop::ShouldRun(const Program* program, const DataMap&) const {
+bool ShouldRun(const Program* program) {
for (auto* node : program->ASTNodes().Objects()) {
if (node->Is<ast::WhileStatement>()) {
return true;
@@ -34,20 +33,32 @@
return false;
}
-void WhileToLoop::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+} // namespace
+
+WhileToLoop::WhileToLoop() = default;
+
+WhileToLoop::~WhileToLoop() = default;
+
+Transform::ApplyResult WhileToLoop::Apply(const Program* src, const DataMap&, DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
+ }
+
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
ctx.ReplaceAll([&](const ast::WhileStatement* w) -> const ast::Statement* {
utils::Vector<const ast::Statement*, 16> stmts;
auto* cond = w->condition;
// !condition
- auto* not_cond =
- ctx.dst->create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, ctx.Clone(cond));
+ auto* not_cond = b.Not(ctx.Clone(cond));
// { break; }
- auto* break_body = ctx.dst->Block(ctx.dst->create<ast::BreakStatement>());
+ auto* break_body = b.Block(b.Break());
// if (!condition) { break; }
- stmts.Push(ctx.dst->If(not_cond, break_body));
+ stmts.Push(b.If(not_cond, break_body));
for (auto* stmt : w->body->statements) {
stmts.Push(ctx.Clone(stmt));
@@ -55,13 +66,14 @@
const ast::BlockStatement* continuing = nullptr;
- auto* body = ctx.dst->Block(stmts);
- auto* loop = ctx.dst->create<ast::LoopStatement>(body, continuing);
+ auto* body = b.Block(stmts);
+ auto* loop = b.Loop(body, continuing);
return loop;
});
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/while_to_loop.h b/src/tint/transform/while_to_loop.h
index 4915d68..187799a 100644
--- a/src/tint/transform/while_to_loop.h
+++ b/src/tint/transform/while_to_loop.h
@@ -29,19 +29,10 @@
/// Destructor
~WhileToLoop() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
};
} // namespace tint::transform
diff --git a/src/tint/transform/zero_init_workgroup_memory.cc b/src/tint/transform/zero_init_workgroup_memory.cc
index ea65436..ed3584e 100644
--- a/src/tint/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/transform/zero_init_workgroup_memory.cc
@@ -31,10 +31,24 @@
TINT_INSTANTIATE_TYPEINFO(tint::transform::ZeroInitWorkgroupMemory);
namespace tint::transform {
+namespace {
+
+bool ShouldRun(const Program* program) {
+ for (auto* global : program->AST().GlobalVariables()) {
+ if (auto* var = global->As<ast::Var>()) {
+ if (var->declared_address_space == ast::AddressSpace::kWorkgroup) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+} // namespace
using StatementList = utils::Vector<const ast::Statement*, 8>;
-/// PIMPL state for the ZeroInitWorkgroupMemory transform
+/// PIMPL state for the transform
struct ZeroInitWorkgroupMemory::State {
/// The clone context
CloneContext& ctx;
@@ -424,24 +438,24 @@
ZeroInitWorkgroupMemory::~ZeroInitWorkgroupMemory() = default;
-bool ZeroInitWorkgroupMemory::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* global : program->AST().GlobalVariables()) {
- if (auto* var = global->As<ast::Var>()) {
- if (var->declared_address_space == ast::AddressSpace::kWorkgroup) {
- return true;
- }
- }
+Transform::ApplyResult ZeroInitWorkgroupMemory::Apply(const Program* src,
+ const DataMap&,
+ DataMap&) const {
+ if (!ShouldRun(src)) {
+ return SkipTransform;
}
- return false;
-}
-void ZeroInitWorkgroupMemory::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- for (auto* fn : ctx.src->AST().Functions()) {
+ ProgramBuilder b;
+ CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
+
+ for (auto* fn : src->AST().Functions()) {
if (fn->PipelineStage() == ast::PipelineStage::kCompute) {
State{ctx}.Run(fn);
}
}
+
ctx.Clone();
+ return Program(std::move(b));
}
} // namespace tint::transform
diff --git a/src/tint/transform/zero_init_workgroup_memory.h b/src/tint/transform/zero_init_workgroup_memory.h
index 07feaa8..64f4da8 100644
--- a/src/tint/transform/zero_init_workgroup_memory.h
+++ b/src/tint/transform/zero_init_workgroup_memory.h
@@ -30,19 +30,10 @@
/// Destructor
~ZeroInitWorkgroupMemory() override;
- /// @param program the program to inspect
- /// @param data optional extra transform-specific input data
- /// @returns true if this transform should be run for the given program
- bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
-
- protected:
- /// Runs the transform using the CloneContext built for transforming a
- /// program. Run() is responsible for calling Clone() on the CloneContext.
- /// @param ctx the CloneContext primed with the input program and
- /// ProgramBuilder
- /// @param inputs optional extra transform-specific input data
- /// @param outputs optional extra transform-specific output data
- void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
private:
struct State;
diff --git a/src/tint/utils/hashmap.h b/src/tint/utils/hashmap.h
index 87a0dd9..1040e0c 100644
--- a/src/tint/utils/hashmap.h
+++ b/src/tint/utils/hashmap.h
@@ -19,255 +19,119 @@
#include <optional>
#include <utility>
+#include "src/tint/debug.h"
#include "src/tint/utils/hash.h"
-#include "src/tint/utils/hashset.h"
+#include "src/tint/utils/hashmap_base.h"
+#include "src/tint/utils/vector.h"
namespace tint::utils {
/// An unordered map that uses a robin-hood hashing algorithm.
-///
-/// Hashmap internally wraps a Hashset for providing a store for key-value pairs.
-///
-/// @see Hashset
-template <typename K,
- typename V,
+template <typename KEY,
+ typename VALUE,
size_t N,
- typename HASH = Hasher<K>,
- typename EQUAL = std::equal_to<K>>
-class Hashmap {
- /// Entry holds a key and value pair, and is used as the element type of the underlying Hashset.
- /// Entries are compared and hashed using only the #key.
- /// @see Hasher
- /// @see Equality
- struct Entry {
- /// Constructor from a key and value pair
- Entry(K k, V v) : key(std::move(k)), value(std::move(v)) {}
-
- /// Copy-constructor.
- Entry(const Entry&) = default;
-
- /// Move-constructor.
- Entry(Entry&&) = default;
-
- /// Copy-assignment operator
- Entry& operator=(const Entry&) = default;
-
- /// Move-assignment operator
- Entry& operator=(Entry&&) = default;
-
- K key; /// The map entry key
- V value; /// The map entry value
- };
-
- /// Hash provider for the underlying Hashset.
- /// Provides hash functions for an Entry or K.
- /// The hash functions only consider the key of an entry.
- struct Hasher {
- /// Calculates a hash from an Entry
- size_t operator()(const Entry& entry) const { return HASH()(entry.key); }
- /// Calculates a hash from a K
- size_t operator()(const K& key) const { return HASH()(key); }
- };
-
- /// Equality provider for the underlying Hashset.
- /// Provides equality functions for an Entry or K to an Entry.
- /// The equality functions only consider the key for equality.
- struct Equality {
- /// Compares an Entry to an Entry for equality.
- bool operator()(const Entry& a, const Entry& b) const { return EQUAL()(a.key, b.key); }
- /// Compares a K to an Entry for equality.
- bool operator()(const K& a, const Entry& b) const { return EQUAL()(a, b.key); }
- };
-
- /// The underlying set
- using Set = Hashset<Entry, N, Hasher, Equality>;
+ typename HASH = Hasher<KEY>,
+ typename EQUAL = std::equal_to<KEY>>
+class Hashmap : public HashmapBase<KEY, VALUE, N, HASH, EQUAL> {
+ using Base = HashmapBase<KEY, VALUE, N, HASH, EQUAL>;
+ using PutMode = typename Base::PutMode;
public:
- /// A Key and Value const-reference pair.
- struct KeyValue {
- /// key of a map entry
- const K& key;
- /// value of a map entry
- const V& value;
+ /// The key type
+ using Key = KEY;
+ /// The value type
+ using Value = VALUE;
+ /// The key-value type for a map entry
+ using Entry = KeyValue<Key, Value>;
- /// Equality operator
- /// @param other the other KeyValue
- /// @returns true if the key and value of this KeyValue are equal to other's.
- bool operator==(const KeyValue& other) const {
- return key == other.key && value == other.value;
- }
- };
+ /// Result of Add()
+ using AddResult = typename Base::PutResult;
- /// STL-style alias to KeyValue.
- /// Used by gmock for the `ElementsAre` checks.
- using value_type = KeyValue;
-
- /// Iterator for the map.
- /// Iterators are invalidated if the map is modified.
- class Iterator {
- public:
- /// @returns the key of the entry pointed to by this iterator
- const K& Key() const { return it->key; }
-
- /// @returns the value of the entry pointed to by this iterator
- const V& Value() const { return it->value; }
-
- /// Increments the iterator
- /// @returns this iterator
- Iterator& operator++() {
- ++it;
- return *this;
- }
-
- /// Equality operator
- /// @param other the other iterator to compare this iterator to
- /// @returns true if this iterator is equal to other
- bool operator==(const Iterator& other) const { return it == other.it; }
-
- /// Inequality operator
- /// @param other the other iterator to compare this iterator to
- /// @returns true if this iterator is not equal to other
- bool operator!=(const Iterator& other) const { return it != other.it; }
-
- /// @returns a pair of key and value for the entry pointed to by this iterator
- KeyValue operator*() const { return {Key(), Value()}; }
-
- private:
- /// Friend class
- friend class Hashmap;
-
- /// Underlying iterator type
- using SetIterator = typename Set::Iterator;
-
- explicit Iterator(SetIterator i) : it(i) {}
-
- SetIterator it;
- };
-
- /// Removes all entries from the map.
- void Clear() { set_.Clear(); }
-
- /// Adds the key-value pair to the map, if the map does not already contain an entry with a key
- /// equal to `key`.
- /// @param key the entry's key to add to the map
- /// @param value the entry's value to add to the map
- /// @returns true if the entry was added to the map, false if there was already an entry in the
- /// map with a key equal to `key`.
- template <typename KEY, typename VALUE>
- bool Add(KEY&& key, VALUE&& value) {
- return set_.Add(Entry{std::forward<KEY>(key), std::forward<VALUE>(value)});
+ /// Adds a value to the map, if the map does not already contain an entry with the key @p key.
+ /// @param key the entry key.
+ /// @param value the value of the entry to add to the map.
+ /// @returns A AddResult describing the result of the add
+ template <typename K, typename V>
+ AddResult Add(K&& key, V&& value) {
+ return this->template Put<PutMode::kAdd>(std::forward<K>(key), std::forward<V>(value));
}
- /// Adds the key-value pair to the map, replacing any entry with a key equal to `key`.
- /// @param key the entry's key to add to the map
- /// @param value the entry's value to add to the map
- template <typename KEY, typename VALUE>
- void Replace(KEY&& key, VALUE&& value) {
- set_.Replace(Entry{std::forward<KEY>(key), std::forward<VALUE>(value)});
+ /// Adds a new entry to the map, replacing any entry that has a key equal to @p key.
+ /// @param key the entry key.
+ /// @param value the value of the entry to add to the map.
+ /// @returns A AddResult describing the result of the replace
+ template <typename K, typename V>
+ AddResult Replace(K&& key, V&& value) {
+ return this->template Put<PutMode::kReplace>(std::forward<K>(key), std::forward<V>(value));
}
- /// Searches for an entry with the given key value.
- /// @param key the entry's key value to search for.
- /// @returns the value of the entry with the given key, or no value if the entry was not found.
- std::optional<V> Get(const K& key) {
- if (auto* entry = set_.Find(key)) {
- return entry->value;
+ /// @param key the key to search for.
+ /// @returns the value of the entry that is equal to `value`, or no value if the entry was not
+ /// found.
+ std::optional<Value> Get(const Key& key) const {
+ if (auto [found, index] = this->IndexOf(key); found) {
+ return this->slots_[index].entry->value;
}
return std::nullopt;
}
- /// Searches for an entry with the given key value, adding and returning the result of
- /// calling `create` if the entry was not found.
+ /// Searches for an entry with the given key, adding and returning the result of calling
+ /// @p create if the entry was not found.
/// @note: Before calling `create`, the map will insert a zero-initialized value for the given
- /// key, which will be replaced with the value returned by `create`. If `create` adds an entry
- /// with `key` to this map, it will be replaced.
+ /// key, which will be replaced with the value returned by @p create. If @p create adds an entry
+ /// with @p key to this map, it will be replaced.
/// @param key the entry's key value to search for.
/// @param create the create function to call if the map does not contain the key.
/// @returns the value of the entry.
- template <typename CREATE>
- V& GetOrCreate(const K& key, CREATE&& create) {
- auto res = set_.Add(Entry{key, V{}});
- if (res.action == AddAction::kAdded) {
- // Store the set generation before calling create()
- auto generation = set_.Generation();
+ template <typename K, typename CREATE>
+ Value& GetOrCreate(K&& key, CREATE&& create) {
+ auto res = Add(std::forward<K>(key), Value{});
+ if (res.action == MapAction::kAdded) {
+ // Store the map generation before calling create()
+ auto generation = this->Generation();
// Call create(), which might modify this map.
auto value = create();
// Was this map mutated?
- if (set_.Generation() == generation) {
+ if (this->Generation() == generation) {
// Calling create() did not touch the map. No need to lookup again.
- res.entry->value = std::move(value);
+ *res.value = std::move(value);
} else {
// Calling create() modified the map. Need to insert again.
- res = set_.Replace(Entry{key, std::move(value)});
+ res = Replace(key, std::move(value));
}
}
- return res.entry->value;
+ return *res.value;
}
/// Searches for an entry with the given key value, adding and returning a newly created
/// zero-initialized value if the entry was not found.
/// @param key the entry's key value to search for.
/// @returns the value of the entry.
- V& GetOrZero(const K& key) {
- auto res = set_.Add(Entry{key, V{}});
- return res.entry->value;
+ template <typename K>
+ Value& GetOrZero(K&& key) {
+ auto res = Add(std::forward<K>(key), Value{});
+ return *res.value;
}
- /// Searches for an entry with the given key value.
- /// @param key the entry's key value to search for.
- /// @returns the a pointer to the value of the entry with the given key, or nullptr if the entry
- /// was not found.
- /// @warning the pointer must not be used after the map is mutated
- V* Find(const K& key) {
- if (auto* entry = set_.Find(key)) {
- return &entry->value;
+ /// @param key the key to search for.
+ /// @returns a pointer to the entry that is equal to the given value, or nullptr if the map does
+ /// not contain the given value.
+ const Value* Find(const Key& key) const {
+ if (auto [found, index] = this->IndexOf(key); found) {
+ return &this->slots_[index].entry->value;
}
return nullptr;
}
- /// Searches for an entry with the given key value.
- /// @param key the entry's key value to search for.
- /// @returns the a pointer to the value of the entry with the given key, or nullptr if the entry
- /// was not found.
- /// @warning the pointer must not be used after the map is mutated
- const V* Find(const K& key) const {
- if (auto* entry = set_.Find(key)) {
- return &entry->value;
+ /// @param key the key to search for.
+ /// @returns a pointer to the entry that is equal to the given value, or nullptr if the map does
+ /// not contain the given value.
+ Value* Find(const Key& key) {
+ if (auto [found, index] = this->IndexOf(key); found) {
+ return &this->slots_[index].entry->value;
}
return nullptr;
}
-
- /// Removes an entry from the set with a key equal to `key`.
- /// @param key the entry key value to remove.
- /// @returns true if an entry was removed.
- bool Remove(const K& key) { return set_.Remove(key); }
-
- /// Checks whether an entry exists in the map with a key equal to `key`.
- /// @param key the entry key value to search for.
- /// @returns true if the map contains an entry with the given key.
- bool Contains(const K& key) const { return set_.Contains(key); }
-
- /// Pre-allocates memory so that the map can hold at least `capacity` entries.
- /// @param capacity the new capacity of the map.
- void Reserve(size_t capacity) { set_.Reserve(capacity); }
-
- /// @returns the number of entries in the map.
- size_t Count() const { return set_.Count(); }
-
- /// @returns a monotonic counter which is incremented whenever the map is mutated.
- size_t Generation() const { return set_.Generation(); }
-
- /// @returns true if the map contains no entries.
- bool IsEmpty() const { return set_.IsEmpty(); }
-
- /// @returns an iterator to the start of the map
- Iterator begin() const { return Iterator{set_.begin()}; }
-
- /// @returns an iterator to the end of the map
- Iterator end() const { return Iterator{set_.end()}; }
-
- private:
- Set set_;
};
} // namespace tint::utils
diff --git a/src/tint/utils/hashmap_base.h b/src/tint/utils/hashmap_base.h
new file mode 100644
index 0000000..ca0712a
--- /dev/null
+++ b/src/tint/utils/hashmap_base.h
@@ -0,0 +1,570 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_UTILS_HASHMAP_BASE_H_
+#define SRC_TINT_UTILS_HASHMAP_BASE_H_
+
+#include <algorithm>
+#include <functional>
+#include <optional>
+#include <tuple>
+#include <utility>
+
+#include "src/tint/debug.h"
+#include "src/tint/utils/hash.h"
+#include "src/tint/utils/vector.h"
+
+namespace tint::utils {
+
+/// Action taken by a map mutation
+enum class MapAction {
+ /// A new entry was added to the map
+ kAdded,
+ /// A existing entry in the map was replaced
+ kReplaced,
+ /// No action was taken as the map already contained an entry with the given key
+ kKeptExisting,
+};
+
+/// KeyValue is a key-value pair.
+template <typename KEY, typename VALUE>
+struct KeyValue {
+ /// The key type
+ using Key = KEY;
+ /// The value type
+ using Value = VALUE;
+
+ /// The key
+ Key key;
+
+ /// The value
+ Value value;
+
+ /// Equality operator
+ /// @param other the RHS of the operator
+ /// @returns true if both the key and value of this KeyValue are equal to the key and value
+ /// of @p other
+ template <typename K, typename V>
+ bool operator==(const KeyValue<K, V>& other) const {
+ return key == other.key && value == other.value;
+ }
+
+ /// Inequality operator
+ /// @param other the RHS of the operator
+ /// @returns true if either the key and value of this KeyValue are not equal to the key and
+ /// value of @p other
+ template <typename K, typename V>
+ bool operator!=(const KeyValue<K, V>& other) const {
+ return *this != other;
+ }
+};
+
+/// Writes the KeyValue to the std::ostream.
+/// @param out the std::ostream to write to
+/// @param key_value the KeyValue to write
+/// @returns out so calls can be chained
+template <typename KEY, typename VALUE>
+std::ostream& operator<<(std::ostream& out, const KeyValue<KEY, VALUE>& key_value) {
+ return out << "[" << key_value.key << ": " << key_value.value << "]";
+}
+
+/// A base class for Hashmap and Hashset that uses a robin-hood hashing algorithm.
+/// @see the fantastic tutorial: https://programming.guide/robin-hood-hashing.html
+template <typename KEY,
+ typename VALUE,
+ size_t N,
+ typename HASH = Hasher<KEY>,
+ typename EQUAL = std::equal_to<KEY>>
+class HashmapBase {
+ static constexpr bool ValueIsVoid = std::is_same_v<VALUE, void>;
+
+ public:
+ /// The key type
+ using Key = KEY;
+ /// The value type
+ using Value = VALUE;
+ /// The entry type for the map.
+ /// This is:
+ /// - Key when Value is void (used by Hashset)
+ /// - KeyValue<Key, Value> when Value is void (used by Hashmap)
+ using Entry = std::conditional_t<ValueIsVoid, Key, KeyValue<Key, Value>>;
+
+ /// STL-friendly alias to Entry. Used by gmock.
+ using value_type = Entry;
+
+ private:
+ /// @returns the key from an entry
+ static const Key& KeyOf(const Entry& entry) {
+ if constexpr (ValueIsVoid) {
+ return entry;
+ } else {
+ return entry.key;
+ }
+ }
+
+ /// @returns a pointer to the value from an entry.
+ static Value* ValueOf(Entry& entry) {
+ if constexpr (ValueIsVoid) {
+ return nullptr; // Hashset only has keys
+ } else {
+ return &entry.value;
+ }
+ }
+
+ /// A slot is a single entry in the underlying vector.
+ /// A slot can either be empty or filled with a value. If the slot is empty, #hash and #distance
+ /// will be zero.
+ struct Slot {
+ bool Equals(size_t key_hash, const Key& key) const {
+ return key_hash == hash && EQUAL()(key, KeyOf(*entry));
+ }
+
+ /// The slot value. If this does not contain a value, then the slot is vacant.
+ std::optional<Entry> entry;
+ /// The precomputed hash of value.
+ size_t hash = 0;
+ size_t distance = 0;
+ };
+
+ /// The target length of the underlying vector length in relation to the number of entries in
+ /// the map, expressed as a percentage. For example a value of `150` would mean there would be
+ /// at least 50% more slots than the number of map entries.
+ static constexpr size_t kRehashFactor = 150;
+
+ /// @returns the target slot vector size to hold `n` map entries.
+ static constexpr size_t NumSlots(size_t count) { return (count * kRehashFactor) / 100; }
+
+ /// The fixed-size slot vector length, based on N and kRehashFactor.
+ static constexpr size_t kNumFixedSlots = NumSlots(N);
+
+ /// The minimum number of slots for the map.
+ static constexpr size_t kMinSlots = std::max<size_t>(kNumFixedSlots, 4);
+
+ public:
+ /// Iterator for entries in the map.
+ /// Iterators are invalidated if the map is modified.
+ class Iterator {
+ public:
+ /// @returns the value pointed to by this iterator
+ const Entry* operator->() const { return ¤t->entry.value(); }
+
+ /// @returns a reference to the value at the iterator
+ const Entry& operator*() const { return current->entry.value(); }
+
+ /// Increments the iterator
+ /// @returns this iterator
+ Iterator& operator++() {
+ if (current == end) {
+ return *this;
+ }
+ current++;
+ SkipToNextValue();
+ return *this;
+ }
+
+ /// Equality operator
+ /// @param other the other iterator to compare this iterator to
+ /// @returns true if this iterator is equal to other
+ bool operator==(const Iterator& other) const { return current == other.current; }
+
+ /// Inequality operator
+ /// @param other the other iterator to compare this iterator to
+ /// @returns true if this iterator is not equal to other
+ bool operator!=(const Iterator& other) const { return current != other.current; }
+
+ private:
+ /// Friend class
+ friend class HashmapBase;
+
+ Iterator(const Slot* c, const Slot* e) : current(c), end(e) { SkipToNextValue(); }
+
+ /// Moves the iterator forward, stopping at the next slot that is not empty.
+ void SkipToNextValue() {
+ while (current != end && !current->entry.has_value()) {
+ current++;
+ }
+ }
+
+ const Slot* current; /// The slot the iterator is pointing to
+ const Slot* end; /// One past the last slot in the map
+ };
+
+ /// Constructor
+ HashmapBase() { slots_.Resize(kMinSlots); }
+
+ /// Copy constructor
+ /// @param other the other HashmapBase to copy
+ HashmapBase(const HashmapBase& other) = default;
+
+ /// Move constructor
+ /// @param other the other HashmapBase to move
+ HashmapBase(HashmapBase&& other) = default;
+
+ /// Destructor
+ ~HashmapBase() { Clear(); }
+
+ /// Copy-assignment operator
+ /// @param other the other HashmapBase to copy
+ /// @returns this so calls can be chained
+ HashmapBase& operator=(const HashmapBase& other) = default;
+
+ /// Move-assignment operator
+ /// @param other the other HashmapBase to move
+ /// @returns this so calls can be chained
+ HashmapBase& operator=(HashmapBase&& other) = default;
+
+ /// Removes all entries from the map.
+ void Clear() {
+ slots_.Clear(); // Destructs all entries
+ slots_.Resize(kMinSlots);
+ count_ = 0;
+ generation_++;
+ }
+
+ /// Removes an entry from the map.
+ /// @param key the entry key.
+ /// @returns true if an entry was removed.
+ bool Remove(const Key& key) {
+ const auto [found, start] = IndexOf(key);
+ if (!found) {
+ return false;
+ }
+
+ // Shuffle the entries backwards until we either find a free slot, or a slot that has zero
+ // distance.
+ Slot* prev = nullptr;
+ Scan(start, [&](size_t, size_t index) {
+ auto& slot = slots_[index];
+ if (prev) {
+ // note: `distance == 0` also includes empty slots.
+ if (slot.distance == 0) {
+ // Clear the previous slot, and stop shuffling.
+ *prev = {};
+ return Action::kStop;
+ } else {
+ // Shuffle the slot backwards.
+ prev->entry = std::move(slot.entry);
+ prev->hash = slot.hash;
+ prev->distance = slot.distance - 1;
+ }
+ }
+ prev = &slot;
+ return Action::kContinue;
+ });
+
+ // Entry was removed.
+ count_--;
+ generation_++;
+
+ return true;
+ }
+
+ /// Checks whether an entry exists in the map
+ /// @param key the key to search for.
+ /// @returns true if the map contains an entry with the given value.
+ bool Contains(const Key& key) const {
+ const auto [found, _] = IndexOf(key);
+ return found;
+ }
+
+ /// Pre-allocates memory so that the map can hold at least `capacity` entries.
+ /// @param capacity the new capacity of the map.
+ void Reserve(size_t capacity) {
+ // Calculate the number of slots required to hold `capacity` entries.
+ const size_t num_slots = std::max(NumSlots(capacity), kMinSlots);
+ if (slots_.Length() >= num_slots) {
+ // Already have enough slots.
+ return;
+ }
+
+ // Move all the values out of the map and into a vector.
+ Vector<Entry, N> entries;
+ entries.Reserve(count_);
+ for (auto& slot : slots_) {
+ if (slot.entry.has_value()) {
+ entries.Push(std::move(slot.entry.value()));
+ }
+ }
+
+ // Clear the map, grow the number of slots.
+ Clear();
+ slots_.Resize(num_slots);
+
+ // As the number of slots has grown, the slot indices will have changed from before, so
+ // re-add all the entries back into the map.
+ for (auto& entry : entries) {
+ if constexpr (ValueIsVoid) {
+ struct NoValue {};
+ Put<PutMode::kAdd>(std::move(entry), NoValue{});
+ } else {
+ Put<PutMode::kAdd>(std::move(entry.key), std::move(entry.value));
+ }
+ }
+ }
+
+ /// @returns the number of entries in the map.
+ size_t Count() const { return count_; }
+
+ /// @returns true if the map contains no entries.
+ bool IsEmpty() const { return count_ == 0; }
+
+ /// @returns a monotonic counter which is incremented whenever the map is mutated.
+ size_t Generation() const { return generation_; }
+
+ /// @returns an iterator to the start of the map.
+ Iterator begin() const { return Iterator{slots_.begin(), slots_.end()}; }
+
+ /// @returns an iterator to the end of the map.
+ Iterator end() const { return Iterator{slots_.end(), slots_.end()}; }
+
+ /// A debug function for checking that the map is in good health.
+ /// Asserts if the map is corrupted.
+ void ValidateIntegrity() const {
+ size_t num_alive = 0;
+ for (size_t slot_idx = 0; slot_idx < slots_.Length(); slot_idx++) {
+ const auto& slot = slots_[slot_idx];
+ if (slot.entry.has_value()) {
+ num_alive++;
+ auto const [index, hash] = Hash(KeyOf(*slot.entry));
+ TINT_ASSERT(Utils, hash == slot.hash);
+ TINT_ASSERT(Utils, slot_idx == Wrap(index + slot.distance));
+ }
+ }
+ TINT_ASSERT(Utils, num_alive == count_);
+ }
+
+ protected:
+ /// The behaviour of Put() when an entry already exists with the given key.
+ enum class PutMode {
+ /// Do not replace existing entries with the new value.
+ kAdd,
+ /// Replace existing entries with the new value.
+ kReplace,
+ };
+
+ /// Result of Put()
+ struct PutResult {
+ /// Whether the insert replaced or added a new entry to the map.
+ MapAction action = MapAction::kAdded;
+ /// A pointer to the inserted entry value.
+ Value* value = nullptr;
+
+ /// @returns true if the entry was added to the map, or an existing entry was replaced.
+ operator bool() const { return action != MapAction::kKeptExisting; }
+ };
+
+ /// The common implementation for Add() and Replace()
+ /// @param key the key of the entry to add to the map.
+ /// @param value the value of the entry to add to the map.
+ /// @returns A PutResult describing the result of the insertion
+ template <PutMode MODE, typename K, typename V>
+ PutResult Put(K&& key, V&& value) {
+ // Ensure the map can fit a new entry
+ if (ShouldRehash(count_ + 1)) {
+ Reserve((count_ + 1) * 2);
+ }
+
+ const auto hash = Hash(key);
+
+ auto make_entry = [&]() {
+ if constexpr (ValueIsVoid) {
+ return std::forward<K>(key);
+ } else {
+ return Entry{std::forward<K>(key), std::forward<V>(value)};
+ }
+ };
+
+ PutResult result{};
+ Scan(hash.scan_start, [&](size_t distance, size_t index) {
+ auto& slot = slots_[index];
+ if (!slot.entry.has_value()) {
+ // Found an empty slot.
+ // Place value directly into the slot, and we're done.
+ slot.entry.emplace(make_entry());
+ slot.hash = hash.code;
+ slot.distance = distance;
+ count_++;
+ generation_++;
+ result = PutResult{MapAction::kAdded, ValueOf(*slot.entry)};
+ return Action::kStop;
+ }
+
+ // Slot has an entry
+
+ if (slot.Equals(hash.code, key)) {
+ // Slot is equal to value. Replace or preserve?
+ if constexpr (MODE == PutMode::kReplace) {
+ slot.entry = make_entry();
+ generation_++;
+ result = PutResult{MapAction::kReplaced, ValueOf(*slot.entry)};
+ } else {
+ result = PutResult{MapAction::kKeptExisting, ValueOf(*slot.entry)};
+ }
+ return Action::kStop;
+ }
+
+ if (slot.distance < distance) {
+ // Existing slot has a closer distance than the value we're attempting to insert.
+ // Steal from the rich!
+ // Move the current slot to a temporary (evicted), and put the value into the slot.
+ Slot evicted{make_entry(), hash.code, distance};
+ std::swap(evicted, slot);
+
+ // Find a new home for the evicted slot.
+ evicted.distance++; // We've already swapped at index.
+ InsertShuffle(Wrap(index + 1), std::move(evicted));
+
+ count_++;
+ generation_++;
+ result = PutResult{MapAction::kAdded, ValueOf(*slot.entry)};
+
+ return Action::kStop;
+ }
+ return Action::kContinue;
+ });
+
+ return result;
+ }
+
+ /// Return type of the Scan() callback.
+ enum class Action {
+ /// Continue scanning for a slot
+ kContinue,
+ /// Immediately stop scanning for a slot
+ kStop,
+ };
+
+ /// Sequentially visits each of the slots starting with the slot with the index @p start,
+ /// calling the callback function @p f for each slot until @p f returns Action::kStop.
+ /// @param start the index of the first slot to start scanning from.
+ /// @param f the callback function which:
+ /// * must be a function with the signature `Action(size_t distance, size_t index)`.
+ /// * must return Action::kStop within one whole cycle of the slots.
+ template <typename F>
+ void Scan(size_t start, F&& f) const {
+ size_t distance = 0;
+ for (size_t index = start; index < slots_.Length(); index++) {
+ if (f(distance, index) == Action::kStop) {
+ return;
+ }
+ distance++;
+ }
+ for (size_t index = 0; index < start; index++) {
+ if (f(distance, index) == Action::kStop) {
+ return;
+ }
+ distance++;
+ }
+ tint::diag::List diags;
+ TINT_ICE(Utils, diags) << "HashmapBase::Scan() looped entire map without finding a slot";
+ }
+
+ /// HashResult is the return value of Hash()
+ struct HashResult {
+ /// The target (zero-distance) slot index for the key.
+ size_t scan_start;
+ /// The calculated hash code of the key.
+ size_t code;
+ };
+
+ /// @param key the key to hash
+ /// @returns a tuple holding the target slot index for the given value, and the hash of the
+ /// value, respectively.
+ HashResult Hash(const Key& key) const {
+ size_t hash = HASH()(key);
+ size_t index = Wrap(hash);
+ return {index, hash};
+ }
+
+ /// Looks for the key in the map.
+ /// @param key the key to search for.
+ /// @returns a tuple holding a boolean representing whether the key was found in the map, and
+ /// if found, the index of the slot that holds the key.
+ std::tuple<bool, size_t> IndexOf(const Key& key) const {
+ const auto hash = Hash(key);
+
+ bool found = false;
+ size_t idx = 0;
+
+ Scan(hash.scan_start, [&](size_t distance, size_t index) {
+ auto& slot = slots_[index];
+ if (!slot.entry.has_value()) {
+ return Action::kStop;
+ }
+ if (slot.Equals(hash.code, key)) {
+ found = true;
+ idx = index;
+ return Action::kStop;
+ }
+ if (slot.distance < distance) {
+ // If the slot distance is less than the current probe distance, then the slot must
+ // be for entry that has an index that comes after key. In this situation, we know
+ // that the map does not contain the key, as it would have been found before this
+ // slot. The "Lookup" section of https://programming.guide/robin-hood-hashing.html
+ // suggests that the condition should inverted, but this is wrong.
+ return Action::kStop;
+ }
+ return Action::kContinue;
+ });
+
+ return {found, idx};
+ }
+
+ /// Shuffles slots for an insertion that has been placed one slot before `start`.
+ /// @param start the index of the first slot to start shuffling.
+ /// @param evicted the slot content that was evicted for the insertion.
+ void InsertShuffle(size_t start, Slot evicted) {
+ Scan(start, [&](size_t, size_t index) {
+ auto& slot = slots_[index];
+
+ if (!slot.entry.has_value()) {
+ // Empty slot found for evicted.
+ slot = std::move(evicted);
+ return Action::kStop; // We're done.
+ }
+
+ if (slot.distance < evicted.distance) {
+ // Occupied slot has shorter distance to evicted.
+ // Swap slot and evicted.
+ std::swap(slot, evicted);
+ }
+
+ // evicted moves further from the target slot...
+ evicted.distance++;
+
+ return Action::kContinue;
+ });
+ }
+
+ /// @param count the number of new entries in the map
+ /// @returns true if the map should grow the slot vector, and rehash the items.
+ bool ShouldRehash(size_t count) const { return NumSlots(count) > slots_.Length(); }
+
+ /// @param index an input value
+ /// @returns the input value modulo the number of slots.
+ size_t Wrap(size_t index) const { return index % slots_.Length(); }
+
+ /// The vector of slots. The vector length is equal to its capacity.
+ Vector<Slot, kNumFixedSlots> slots_;
+
+ /// The number of entries in the map.
+ size_t count_ = 0;
+
+ /// Counter that's incremented with each modification to the map.
+ size_t generation_ = 0;
+};
+
+} // namespace tint::utils
+
+#endif // SRC_TINT_UTILS_HASHMAP_BASE_H_
diff --git a/src/tint/utils/hashmap_test.cc b/src/tint/utils/hashmap_test.cc
index 9a5b01e..77421cf 100644
--- a/src/tint/utils/hashmap_test.cc
+++ b/src/tint/utils/hashmap_test.cc
@@ -92,14 +92,14 @@
TEST(Hashmap, Iterator) {
using Map = Hashmap<int, std::string, 8>;
- using KV = typename Map::KeyValue;
+ using Entry = typename Map::Entry;
Map map;
map.Add(1, "one");
map.Add(4, "four");
map.Add(3, "three");
map.Add(2, "two");
- EXPECT_THAT(map, testing::UnorderedElementsAre(KV{1, "one"}, KV{2, "two"}, KV{3, "three"},
- KV{4, "four"}));
+ EXPECT_THAT(map, testing::UnorderedElementsAre(Entry{1, "one"}, Entry{2, "two"},
+ Entry{3, "three"}, Entry{4, "four"}));
}
TEST(Hashmap, AddMany) {
diff --git a/src/tint/utils/hashset.h b/src/tint/utils/hashset.h
index f7d5efe..53f71f5 100644
--- a/src/tint/utils/hashset.h
+++ b/src/tint/utils/hashset.h
@@ -23,497 +23,26 @@
#include <utility>
#include "src/tint/debug.h"
-#include "src/tint/utils/hash.h"
+#include "src/tint/utils/hashmap.h"
#include "src/tint/utils/vector.h"
namespace tint::utils {
-/// Action taken by Hashset::Insert()
-enum class AddAction {
- /// Insert() added a new entry to the Hashset
- kAdded,
- /// Insert() replaced an existing entry in the Hashset
- kReplaced,
- /// Insert() found an existing entry, which was not replaced.
- kKeptExisting,
-};
-
/// An unordered set that uses a robin-hood hashing algorithm.
-/// @see the fantastic tutorial: https://programming.guide/robin-hood-hashing.html
-template <typename T, size_t N, typename HASH = Hasher<T>, typename EQUAL = std::equal_to<T>>
-class Hashset {
- /// A slot is a single entry in the underlying vector.
- /// A slot can either be empty or filled with a value. If the slot is empty, #hash and #distance
- /// will be zero.
- struct Slot {
- template <typename V>
- bool Equals(size_t value_hash, const V& val) const {
- return value_hash == hash && EQUAL()(val, value.value());
- }
-
- /// The slot value. If this does not contain a value, then the slot is vacant.
- std::optional<T> value;
- /// The precomputed hash of value.
- size_t hash = 0;
- size_t distance = 0;
- };
-
- /// The target length of the underlying vector length in relation to the number of entries in
- /// the set, expressed as a percentage. For example a value of `150` would mean there would be
- /// at least 50% more slots than the number of set entries.
- static constexpr size_t kRehashFactor = 150;
-
- /// @returns the target slot vector size to hold `n` set entries.
- static constexpr size_t NumSlots(size_t count) { return (count * kRehashFactor) / 100; }
-
- /// The fixed-size slot vector length, based on N and kRehashFactor.
- static constexpr size_t kNumFixedSlots = NumSlots(N);
-
- /// The minimum number of slots for the set.
- static constexpr size_t kMinSlots = std::max<size_t>(kNumFixedSlots, 4);
+template <typename KEY, size_t N, typename HASH = Hasher<KEY>, typename EQUAL = std::equal_to<KEY>>
+class Hashset : public HashmapBase<KEY, void, N, HASH, EQUAL> {
+ using Base = HashmapBase<KEY, void, N, HASH, EQUAL>;
+ using PutMode = typename Base::PutMode;
public:
- /// Iterator for entries in the set.
- /// Iterators are invalidated if the set is modified.
- class Iterator {
- public:
- /// @returns the value pointed to by this iterator
- const T* operator->() const { return ¤t->value.value(); }
-
- /// Increments the iterator
- /// @returns this iterator
- Iterator& operator++() {
- if (current == end) {
- return *this;
- }
- current++;
- SkipToNextValue();
- return *this;
- }
-
- /// Equality operator
- /// @param other the other iterator to compare this iterator to
- /// @returns true if this iterator is equal to other
- bool operator==(const Iterator& other) const { return current == other.current; }
-
- /// Inequality operator
- /// @param other the other iterator to compare this iterator to
- /// @returns true if this iterator is not equal to other
- bool operator!=(const Iterator& other) const { return current != other.current; }
-
- /// @returns a reference to the value at the iterator
- const T& operator*() const { return current->value.value(); }
-
- private:
- /// Friend class
- friend class Hashset;
-
- Iterator(const Slot* c, const Slot* e) : current(c), end(e) { SkipToNextValue(); }
-
- /// Moves the iterator forward, stopping at the next slot that is not empty.
- void SkipToNextValue() {
- while (current != end && !current->value.has_value()) {
- current++;
- }
- }
-
- const Slot* current; /// The slot the iterator is pointing to
- const Slot* end; /// One past the last slot in the set
- };
-
- /// Type of `T`.
- using value_type = T;
-
- /// Constructor
- Hashset() { slots_.Resize(kMinSlots); }
-
- /// Copy constructor
- /// @param other the other Hashset to copy
- Hashset(const Hashset& other) = default;
-
- /// Move constructor
- /// @param other the other Hashset to move
- Hashset(Hashset&& other) = default;
-
- /// Destructor
- ~Hashset() { Clear(); }
-
- /// Copy-assignment operator
- /// @param other the other Hashset to copy
- /// @returns this so calls can be chained
- Hashset& operator=(const Hashset& other) = default;
-
- /// Move-assignment operator
- /// @param other the other Hashset to move
- /// @returns this so calls can be chained
- Hashset& operator=(Hashset&& other) = default;
-
- /// Removes all entries from the set.
- void Clear() {
- slots_.Clear(); // Destructs all entries
- slots_.Resize(kMinSlots);
- count_ = 0;
- generation_++;
- }
-
- /// Result of Add()
- struct AddResult {
- /// Whether the insert replaced or added a new entry to the set.
- AddAction action = AddAction::kAdded;
- /// A pointer to the inserted entry.
- /// @warning do not modify this pointer in a way that would cause the equality or hash of
- /// the entry to change. Doing this will corrupt the Hashset.
- T* entry = nullptr;
-
- /// @returns true if the entry was added to the set, or an existing entry was replaced.
- operator bool() const { return action != AddAction::kKeptExisting; }
- };
-
/// Adds a value to the set, if the set does not already contain an entry equal to `value`.
/// @param value the value to add to the set.
- /// @returns A AddResult describing the result of the add
- /// @warning do not modify the inserted entry in a way that would cause the equality of hash of
- /// the entry to change. Doing this will corrupt the Hashset.
+ /// @returns true if the value was added, false if there was an existing value in the set.
template <typename V>
- AddResult Add(V&& value) {
- return Put<PutMode::kAdd>(std::forward<V>(value));
+ bool Add(V&& value) {
+ struct NoValue {};
+ return this->template Put<PutMode::kAdd>(std::forward<V>(value), NoValue{});
}
-
- /// Adds a value to the set, replacing any entry equal to `value`.
- /// @param value the value to add to the set.
- /// @returns A AddResult describing the result of the replace
- template <typename V>
- AddResult Replace(V&& value) {
- return Put<PutMode::kReplace>(std::forward<V>(value));
- }
-
- /// Removes an entry from the set.
- /// @param value the value to remove from the set.
- /// @returns true if an entry was removed.
- template <typename V>
- bool Remove(const V& value) {
- const auto [found, start] = IndexOf(value);
- if (!found) {
- return false;
- }
-
- // Shuffle the entries backwards until we either find a free slot, or a slot that has zero
- // distance.
- Slot* prev = nullptr;
- Scan(start, [&](size_t, size_t index) {
- auto& slot = slots_[index];
- if (prev) {
- // note: `distance == 0` also includes empty slots.
- if (slot.distance == 0) {
- // Clear the previous slot, and stop shuffling.
- *prev = {};
- return Action::kStop;
- } else {
- // Shuffle the slot backwards.
- prev->value = std::move(slot.value);
- prev->hash = slot.hash;
- prev->distance = slot.distance - 1;
- }
- }
- prev = &slot;
- return Action::kContinue;
- });
-
- // Entry was removed.
- count_--;
- generation_++;
-
- return true;
- }
-
- /// @param value the value to search for.
- /// @returns the value of the entry that is equal to `value`, or no value if the entry was not
- /// found.
- template <typename V>
- std::optional<T> Get(const V& value) const {
- if (const auto [found, index] = IndexOf(value); found) {
- return slots_[index].value.value();
- }
- return std::nullopt;
- }
-
- /// @param value the value to search for.
- /// @returns a pointer to the entry that is equal to the given value, or nullptr if the set does
- /// not contain the given value.
- template <typename V>
- const T* Find(const V& value) const {
- const auto [found, index] = IndexOf(value);
- return found ? &slots_[index].value.value() : nullptr;
- }
-
- /// @param value the value to search for.
- /// @returns a pointer to the entry that is equal to the given value, or nullptr if the set does
- /// not contain the given value.
- /// @warning do not modify the inserted entry in a way that would cause the equality of hash of
- /// the entry to change. Doing this will corrupt the Hashset.
- template <typename V>
- T* Find(const V& value) {
- const auto [found, index] = IndexOf(value);
- return found ? &slots_[index].value.value() : nullptr;
- }
-
- /// Checks whether an entry exists in the set
- /// @param value the value to search for.
- /// @returns true if the set contains an entry with the given value.
- template <typename V>
- bool Contains(const V& value) const {
- const auto [found, _] = IndexOf(value);
- return found;
- }
-
- /// Pre-allocates memory so that the set can hold at least `capacity` entries.
- /// @param capacity the new capacity of the set.
- void Reserve(size_t capacity) {
- // Calculate the number of slots required to hold `capacity` entries.
- const size_t num_slots = std::max(NumSlots(capacity), kMinSlots);
- if (slots_.Length() >= num_slots) {
- // Already have enough slots.
- return;
- }
-
- // Move all the values out of the set and into a vector.
- Vector<T, N> values;
- values.Reserve(count_);
- for (auto& slot : slots_) {
- if (slot.value.has_value()) {
- values.Push(std::move(slot.value.value()));
- }
- }
-
- // Clear the set, grow the number of slots.
- Clear();
- slots_.Resize(num_slots);
-
- // As the number of slots has grown, the slot indices will have changed from before, so
- // re-add all the values back into the set.
- for (auto& value : values) {
- Add(std::move(value));
- }
- }
-
- /// @returns the number of entries in the set.
- size_t Count() const { return count_; }
-
- /// @returns true if the set contains no entries.
- bool IsEmpty() const { return count_ == 0; }
-
- /// @returns a monotonic counter which is incremented whenever the set is mutated.
- size_t Generation() const { return generation_; }
-
- /// @returns an iterator to the start of the set.
- Iterator begin() const { return Iterator{slots_.begin(), slots_.end()}; }
-
- /// @returns an iterator to the end of the set.
- Iterator end() const { return Iterator{slots_.end(), slots_.end()}; }
-
- /// A debug function for checking that the set is in good health.
- /// Asserts if the set is corrupted.
- void ValidateIntegrity() const {
- size_t num_alive = 0;
- for (size_t slot_idx = 0; slot_idx < slots_.Length(); slot_idx++) {
- const auto& slot = slots_[slot_idx];
- if (slot.value.has_value()) {
- num_alive++;
- auto const [index, hash] = Hash(slot.value.value());
- TINT_ASSERT(Utils, hash == slot.hash);
- TINT_ASSERT(Utils, slot_idx == Wrap(index + slot.distance));
- }
- }
- TINT_ASSERT(Utils, num_alive == count_);
- }
-
- private:
- /// The behaviour of Put() when an entry already exists with the given key.
- enum class PutMode {
- /// Do not replace existing entries with the new value.
- kAdd,
- /// Replace existing entries with the new value.
- kReplace,
- };
- /// The common implementation for Add() and Replace()
- /// @param value the value to add to the set.
- /// @returns A AddResult describing the result of the insertion
- template <PutMode MODE, typename V>
- AddResult Put(V&& value) {
- // Ensure the set can fit a new entry
- if (ShouldRehash(count_ + 1)) {
- Reserve((count_ + 1) * 2);
- }
-
- const auto hash = Hash(value);
-
- AddResult result{};
- Scan(hash.scan_start, [&](size_t distance, size_t index) {
- auto& slot = slots_[index];
- if (!slot.value.has_value()) {
- // Found an empty slot.
- // Place value directly into the slot, and we're done.
- slot.value.emplace(std::forward<V>(value));
- slot.hash = hash.value;
- slot.distance = distance;
- count_++;
- generation_++;
- result = AddResult{AddAction::kAdded, &slot.value.value()};
- return Action::kStop;
- }
-
- // Slot has an entry
-
- if (slot.Equals(hash.value, value)) {
- // Slot is equal to value. Replace or preserve?
- if constexpr (MODE == PutMode::kReplace) {
- slot.value = std::forward<V>(value);
- generation_++;
- result = AddResult{AddAction::kReplaced, &slot.value.value()};
- } else {
- result = AddResult{AddAction::kKeptExisting, &slot.value.value()};
- }
- return Action::kStop;
- }
-
- if (slot.distance < distance) {
- // Existing slot has a closer distance than the value we're attempting to insert.
- // Steal from the rich!
- // Move the current slot to a temporary (evicted), and put the value into the slot.
- Slot evicted{std::forward<V>(value), hash.value, distance};
- std::swap(evicted, slot);
-
- // Find a new home for the evicted slot.
- evicted.distance++; // We've already swapped at index.
- InsertShuffle(Wrap(index + 1), std::move(evicted));
-
- count_++;
- generation_++;
- result = AddResult{AddAction::kAdded, &slot.value.value()};
-
- return Action::kStop;
- }
- return Action::kContinue;
- });
-
- return result;
- }
-
- /// Return type of the Scan() callback.
- enum class Action {
- /// Continue scanning for a slot
- kContinue,
- /// Immediately stop scanning for a slot
- kStop,
- };
-
- /// Sequentially visits each of the slots starting with the slot with the index `start`, calling
- /// the callback function `f` for each slot until `f` returns Action::kStop.
- /// `f` must be a function with the signature `Action(size_t distance, size_t index)`.
- /// `f` must return Action::kStop within one whole cycle of the slots.
- template <typename F>
- void Scan(size_t start, F&& f) const {
- size_t index = start;
- for (size_t distance = 0; distance < slots_.Length(); distance++) {
- if (f(distance, index) == Action::kStop) {
- return;
- }
- index = Wrap(index + 1);
- }
- tint::diag::List diags;
- TINT_ICE(Utils, diags) << "Hashset::Scan() looped entire set without finding a slot";
- }
-
- /// HashResult is the return value of Hash()
- struct HashResult {
- /// The target (zero-distance) slot index for the value.
- size_t scan_start;
- /// The calculated hash of the value.
- size_t value;
- };
-
- /// @returns a tuple holding the target slot index for the given value, and the hash of the
- /// value, respectively.
- template <typename V>
- HashResult Hash(const V& value) const {
- size_t hash = HASH()(value);
- size_t index = Wrap(hash);
- return {index, hash};
- }
-
- /// Looks for the value in the set.
- /// @returns a tuple holding a boolean representing whether the value was found in the set, and
- /// if found, the index of the slot that holds the value.
- template <typename V>
- std::tuple<bool, size_t> IndexOf(const V& value) const {
- const auto hash = Hash(value);
-
- bool found = false;
- size_t idx = 0;
-
- Scan(hash.scan_start, [&](size_t distance, size_t index) {
- auto& slot = slots_[index];
- if (!slot.value.has_value()) {
- return Action::kStop;
- }
- if (slot.Equals(hash.value, value)) {
- found = true;
- idx = index;
- return Action::kStop;
- }
- if (slot.distance < distance) {
- // If the slot distance is less than the current probe distance, then the slot must
- // be for entry that has an index that comes after value. In this situation, we know
- // that the set does not contain the value, as it would have been found before this
- // slot. The "Lookup" section of https://programming.guide/robin-hood-hashing.html
- // suggests that the condition should inverted, but this is wrong.
- return Action::kStop;
- }
- return Action::kContinue;
- });
-
- return {found, idx};
- }
-
- /// Shuffles slots for an insertion that has been placed one slot before `start`.
- /// @param evicted the slot content that was evicted for the insertion.
- void InsertShuffle(size_t start, Slot evicted) {
- Scan(start, [&](size_t, size_t index) {
- auto& slot = slots_[index];
-
- if (!slot.value.has_value()) {
- // Empty slot found for evicted.
- slot = std::move(evicted);
- return Action::kStop; // We're done.
- }
-
- if (slot.distance < evicted.distance) {
- // Occupied slot has shorter distance to evicted.
- // Swap slot and evicted.
- std::swap(slot, evicted);
- }
-
- // evicted moves further from the target slot...
- evicted.distance++;
-
- return Action::kContinue;
- });
- }
-
- /// @returns true if the set should grow the slot vector, and rehash the items.
- bool ShouldRehash(size_t count) const { return NumSlots(count) > slots_.Length(); }
-
- /// Wrap returns the index value modulo the number of slots.
- size_t Wrap(size_t index) const { return index % slots_.Length(); }
-
- /// The vector of slots. The vector length is equal to its capacity.
- Vector<Slot, kNumFixedSlots> slots_;
-
- /// The number of entries in the set.
- size_t count_ = 0;
-
- /// Counter that's incremented with each modification to the set.
- size_t generation_ = 0;
};
} // namespace tint::utils
diff --git a/src/tint/utils/hashset_test.cc b/src/tint/utils/hashset_test.cc
index 6e8d1cc..64f0da3 100644
--- a/src/tint/utils/hashset_test.cc
+++ b/src/tint/utils/hashset_test.cc
@@ -74,18 +74,12 @@
EXPECT_EQ(set.Generation(), 1u);
set.Add(1);
EXPECT_EQ(set.Generation(), 1u);
- set.Replace(1);
- EXPECT_EQ(set.Generation(), 2u);
set.Add(2);
- EXPECT_EQ(set.Generation(), 3u);
+ EXPECT_EQ(set.Generation(), 2u);
set.Remove(1);
- EXPECT_EQ(set.Generation(), 4u);
+ EXPECT_EQ(set.Generation(), 3u);
set.Clear();
- EXPECT_EQ(set.Generation(), 5u);
- set.Find(2);
- EXPECT_EQ(set.Generation(), 5u);
- set.Get(2);
- EXPECT_EQ(set.Generation(), 5u);
+ EXPECT_EQ(set.Generation(), 4u);
}
TEST(Hashset, Iterator) {
@@ -103,53 +97,30 @@
Hashset<std::string, 8> set;
for (size_t i = 0; i < 1000000; i++) {
std::string value = std::to_string(rnd() & 0x100);
- switch (rnd() % 8) {
+ switch (rnd() % 5) {
case 0: { // Add
auto expected = reference.emplace(value).second;
ASSERT_EQ(set.Add(value), expected) << "i: " << i;
ASSERT_TRUE(set.Contains(value)) << "i: " << i;
break;
}
- case 1: { // Replace
- reference.emplace(value);
- set.Replace(value);
- ASSERT_TRUE(set.Contains(value)) << "i: " << i;
- break;
- }
- case 2: { // Remove
+ case 1: { // Remove
auto expected = reference.erase(value) != 0;
ASSERT_EQ(set.Remove(value), expected) << "i: " << i;
ASSERT_FALSE(set.Contains(value)) << "i: " << i;
break;
}
- case 3: { // Contains
+ case 2: { // Contains
auto expected = reference.count(value) != 0;
ASSERT_EQ(set.Contains(value), expected) << "i: " << i;
break;
}
- case 4: { // Get
- if (reference.count(value) != 0) {
- ASSERT_TRUE(set.Get(value).has_value()) << "i: " << i;
- ASSERT_EQ(set.Get(value), value) << "i: " << i;
- } else {
- ASSERT_FALSE(set.Get(value).has_value()) << "i: " << i;
- }
- break;
- }
- case 5: { // Find
- if (reference.count(value) != 0) {
- ASSERT_EQ(*set.Find(value), value) << "i: " << i;
- } else {
- ASSERT_EQ(set.Find(value), nullptr) << "i: " << i;
- }
- break;
- }
- case 6: { // Copy / Move
+ case 3: { // Copy / Move
Hashset<std::string, 8> tmp(set);
set = std::move(tmp);
break;
}
- case 7: { // Clear
+ case 4: { // Clear
reference.clear();
set.Clear();
break;
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index ab78722..50cdbcf 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -186,6 +186,7 @@
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
+ polyfills.bitshift_modulo = true;
polyfills.count_leading_zeros = true;
polyfills.count_trailing_zeros = true;
polyfills.extract_bits = transform::BuiltinPolyfill::Level::kClampParameters;
@@ -796,6 +797,9 @@
if (builtin->Type() == sem::BuiltinType::kRadians) {
return EmitRadiansCall(out, expr, builtin);
}
+ if (builtin->Type() == sem::BuiltinType::kQuantizeToF16) {
+ return EmitQuantizeToF16Call(out, expr, builtin);
+ }
if (builtin->Type() == sem::BuiltinType::kArrayLength) {
return EmitArrayLength(out, expr);
}
@@ -1287,6 +1291,38 @@
});
}
+bool GeneratorImpl::EmitQuantizeToF16Call(std::ostream& out,
+ const ast::CallExpression* expr,
+ const sem::Builtin* builtin) {
+ // Emulate by casting to f16 and back again.
+ return CallBuiltinHelper(
+ out, expr, builtin, [&](TextBuffer* b, const std::vector<std::string>& params) {
+ const auto v = params[0];
+ if (auto* vec = builtin->ReturnType()->As<sem::Vector>()) {
+ switch (vec->Width()) {
+ case 2: {
+ line(b) << "return unpackHalf2x16(packHalf2x16(" << v << "));";
+ return true;
+ }
+ case 3: {
+ line(b) << "return vec3(";
+ line(b) << " unpackHalf2x16(packHalf2x16(" << v << ".xy)),";
+ line(b) << " unpackHalf2x16(packHalf2x16(" << v << ".zz)).x);";
+ return true;
+ }
+ default: {
+ line(b) << "return vec4(";
+ line(b) << " unpackHalf2x16(packHalf2x16(" << v << ".xy)),";
+ line(b) << " unpackHalf2x16(packHalf2x16(" << v << ".zw)));";
+ return true;
+ }
+ }
+ }
+ line(b) << "return unpackHalf2x16(packHalf2x16(vec2(" << v << "))).x;";
+ return true;
+ });
+}
+
bool GeneratorImpl::EmitBarrierCall(std::ostream& out, const sem::Builtin* builtin) {
// TODO(crbug.com/tint/661): Combine sequential barriers to a single
// instruction.
diff --git a/src/tint/writer/glsl/generator_impl.h b/src/tint/writer/glsl/generator_impl.h
index 889b406..c34880d 100644
--- a/src/tint/writer/glsl/generator_impl.h
+++ b/src/tint/writer/glsl/generator_impl.h
@@ -270,6 +270,14 @@
bool EmitRadiansCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Builtin* builtin);
+ /// Handles generating a call to the `quantizeToF16()` intrinsic
+ /// @param out the output of the expression stream
+ /// @param expr the call expression
+ /// @param builtin the semantic information for the builtin
+ /// @returns true if the call expression is emitted
+ bool EmitQuantizeToF16Call(std::ostream& out,
+ const ast::CallExpression* expr,
+ const sem::Builtin* builtin);
/// Handles a case statement
/// @param stmt the statement
/// @returns true if the statement was emitted successfully
diff --git a/src/tint/writer/glsl/generator_impl_builtin_test.cc b/src/tint/writer/glsl/generator_impl_builtin_test.cc
index 511a309..61d97b0 100644
--- a/src/tint/writer/glsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/glsl/generator_impl_builtin_test.cc
@@ -1266,5 +1266,118 @@
)");
}
+TEST_F(GlslGeneratorImplTest_Builtin, QuantizeToF16_Scalar) {
+ GlobalVar("v", Expr(2_f), ast::AddressSpace::kPrivate);
+ WrapInFunction(Call("quantizeToF16", "v"));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+float tint_quantizeToF16(float param_0) {
+ return unpackHalf2x16(packHalf2x16(vec2(param_0))).x;
+}
+
+
+float v = 2.0f;
+void test_function() {
+ float tint_symbol = tint_quantizeToF16(v);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ test_function();
+ return;
+}
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_Builtin, QuantizeToF16_Vec2) {
+ GlobalVar("v", vec2<f32>(2_f), ast::AddressSpace::kPrivate);
+ WrapInFunction(Call("quantizeToF16", "v"));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+vec2 tint_quantizeToF16(vec2 param_0) {
+ return unpackHalf2x16(packHalf2x16(param_0));
+}
+
+
+vec2 v = vec2(2.0f);
+void test_function() {
+ vec2 tint_symbol = tint_quantizeToF16(v);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ test_function();
+ return;
+}
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_Builtin, QuantizeToF16_Vec3) {
+ GlobalVar("v", vec3<f32>(2_f), ast::AddressSpace::kPrivate);
+ WrapInFunction(Call("quantizeToF16", "v"));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+vec3 tint_quantizeToF16(vec3 param_0) {
+ return vec3(
+ unpackHalf2x16(packHalf2x16(param_0.xy)),
+ unpackHalf2x16(packHalf2x16(param_0.zz)).x);
+}
+
+
+vec3 v = vec3(2.0f);
+void test_function() {
+ vec3 tint_symbol = tint_quantizeToF16(v);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ test_function();
+ return;
+}
+)");
+}
+
+
+TEST_F(GlslGeneratorImplTest_Builtin, QuantizeToF16_Vec4) {
+ GlobalVar("v", vec4<f32>(2_f), ast::AddressSpace::kPrivate);
+ WrapInFunction(Call("quantizeToF16", "v"));
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+vec4 tint_quantizeToF16(vec4 param_0) {
+ return vec4(
+ unpackHalf2x16(packHalf2x16(param_0.xy)),
+ unpackHalf2x16(packHalf2x16(param_0.zw)));
+}
+
+
+vec4 v = vec4(2.0f);
+void test_function() {
+ vec4 tint_symbol = tint_quantizeToF16(v);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ test_function();
+ return;
+}
+)");
+}
+
} // namespace
} // namespace tint::writer::glsl
diff --git a/src/tint/writer/glsl/generator_impl_function_test.cc b/src/tint/writer/glsl/generator_impl_function_test.cc
index 56beefc..0cb72ee 100644
--- a/src/tint/writer/glsl/generator_impl_function_test.cc
+++ b/src/tint/writer/glsl/generator_impl_function_test.cc
@@ -462,13 +462,17 @@
EXPECT_EQ(gen.result(), R"(#version 310 es
precision mediump float;
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
int a;
float b;
+};
+
+layout(binding = 0, std430) buffer coord_block_ssbo {
+ Data inner;
} coord;
void frag_main() {
- float v = coord.b;
+ float v = coord.inner.b;
return;
}
@@ -506,13 +510,17 @@
R"(#version 310 es
precision mediump float;
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
int a;
float b;
+};
+
+layout(binding = 0, std430) buffer coord_block_ssbo {
+ Data inner;
} coord;
void frag_main() {
- float v = coord.b;
+ float v = coord.inner.b;
return;
}
@@ -547,13 +555,17 @@
EXPECT_EQ(gen.result(), R"(#version 310 es
precision mediump float;
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
int a;
float b;
+};
+
+layout(binding = 0, std430) buffer coord_block_ssbo {
+ Data inner;
} coord;
void frag_main() {
- coord.b = 2.0f;
+ coord.inner.b = 2.0f;
return;
}
@@ -588,13 +600,17 @@
EXPECT_EQ(gen.result(), R"(#version 310 es
precision mediump float;
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
int a;
float b;
+};
+
+layout(binding = 0, std430) buffer coord_block_ssbo {
+ Data inner;
} coord;
void frag_main() {
- coord.b = 2.0f;
+ coord.inner.b = 2.0f;
return;
}
@@ -678,12 +694,16 @@
R"(#version 310 es
precision mediump float;
-layout(binding = 0, std430) buffer S_ssbo {
+struct S {
float x;
+};
+
+layout(binding = 0, std430) buffer coord_block_ssbo {
+ S inner;
} coord;
float sub_func(float param) {
- return coord.x;
+ return coord.inner.x;
}
void frag_main() {
@@ -895,12 +915,16 @@
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
float d;
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void a() {
- float v = data.d;
+ float v = data.inner.d;
return;
}
@@ -910,7 +934,7 @@
return;
}
void b() {
- float v = data.d;
+ float v = data.inner.d;
return;
}
diff --git a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
index a7392cd..a906390 100644
--- a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
@@ -179,27 +179,27 @@
INSTANTIATE_TEST_SUITE_P(GlslGeneratorImplTest_MemberAccessor,
GlslGeneratorImplTest_MemberAccessor_StorageBufferLoad,
- testing::Values(TypeCase{ty_u32, "data.b"},
- TypeCase{ty_f32, "data.b"},
- TypeCase{ty_i32, "data.b"},
- TypeCase{ty_vec2<u32>, "data.b"},
- TypeCase{ty_vec2<f32>, "data.b"},
- TypeCase{ty_vec2<i32>, "data.b"},
- TypeCase{ty_vec3<u32>, "data.b"},
- TypeCase{ty_vec3<f32>, "data.b"},
- TypeCase{ty_vec3<i32>, "data.b"},
- TypeCase{ty_vec4<u32>, "data.b"},
- TypeCase{ty_vec4<f32>, "data.b"},
- TypeCase{ty_vec4<i32>, "data.b"},
- TypeCase{ty_mat2x2<f32>, "data.b"},
- TypeCase{ty_mat2x3<f32>, "data.b"},
- TypeCase{ty_mat2x4<f32>, "data.b"},
- TypeCase{ty_mat3x2<f32>, "data.b"},
- TypeCase{ty_mat3x3<f32>, "data.b"},
- TypeCase{ty_mat3x4<f32>, "data.b"},
- TypeCase{ty_mat4x2<f32>, "data.b"},
- TypeCase{ty_mat4x3<f32>, "data.b"},
- TypeCase{ty_mat4x4<f32>, "data.b"}));
+ testing::Values(TypeCase{ty_u32, "data.inner.b"},
+ TypeCase{ty_f32, "data.inner.b"},
+ TypeCase{ty_i32, "data.inner.b"},
+ TypeCase{ty_vec2<u32>, "data.inner.b"},
+ TypeCase{ty_vec2<f32>, "data.inner.b"},
+ TypeCase{ty_vec2<i32>, "data.inner.b"},
+ TypeCase{ty_vec3<u32>, "data.inner.b"},
+ TypeCase{ty_vec3<f32>, "data.inner.b"},
+ TypeCase{ty_vec3<i32>, "data.inner.b"},
+ TypeCase{ty_vec4<u32>, "data.inner.b"},
+ TypeCase{ty_vec4<f32>, "data.inner.b"},
+ TypeCase{ty_vec4<i32>, "data.inner.b"},
+ TypeCase{ty_mat2x2<f32>, "data.inner.b"},
+ TypeCase{ty_mat2x3<f32>, "data.inner.b"},
+ TypeCase{ty_mat2x4<f32>, "data.inner.b"},
+ TypeCase{ty_mat3x2<f32>, "data.inner.b"},
+ TypeCase{ty_mat3x3<f32>, "data.inner.b"},
+ TypeCase{ty_mat3x4<f32>, "data.inner.b"},
+ TypeCase{ty_mat4x2<f32>, "data.inner.b"},
+ TypeCase{ty_mat4x3<f32>, "data.inner.b"},
+ TypeCase{ty_mat4x4<f32>, "data.inner.b"}));
using GlslGeneratorImplTest_MemberAccessor_StorageBufferStore =
GlslGeneratorImplTest_MemberAccessorWithParam<TypeCase>;
@@ -231,27 +231,27 @@
INSTANTIATE_TEST_SUITE_P(GlslGeneratorImplTest_MemberAccessor,
GlslGeneratorImplTest_MemberAccessor_StorageBufferStore,
- testing::Values(TypeCase{ty_u32, "data.b = value"},
- TypeCase{ty_f32, "data.b = value"},
- TypeCase{ty_i32, "data.b = value"},
- TypeCase{ty_vec2<u32>, "data.b = value"},
- TypeCase{ty_vec2<f32>, "data.b = value"},
- TypeCase{ty_vec2<i32>, "data.b = value"},
- TypeCase{ty_vec3<u32>, "data.b = value"},
- TypeCase{ty_vec3<f32>, "data.b = value"},
- TypeCase{ty_vec3<i32>, "data.b = value"},
- TypeCase{ty_vec4<u32>, "data.b = value"},
- TypeCase{ty_vec4<f32>, "data.b = value"},
- TypeCase{ty_vec4<i32>, "data.b = value"},
- TypeCase{ty_mat2x2<f32>, "data.b = value"},
- TypeCase{ty_mat2x3<f32>, "data.b = value"},
- TypeCase{ty_mat2x4<f32>, "data.b = value"},
- TypeCase{ty_mat3x2<f32>, "data.b = value"},
- TypeCase{ty_mat3x3<f32>, "data.b = value"},
- TypeCase{ty_mat3x4<f32>, "data.b = value"},
- TypeCase{ty_mat4x2<f32>, "data.b = value"},
- TypeCase{ty_mat4x3<f32>, "data.b = value"},
- TypeCase{ty_mat4x4<f32>, "data.b = value"}));
+ testing::Values(TypeCase{ty_u32, "data.inner.b = value"},
+ TypeCase{ty_f32, "data.inner.b = value"},
+ TypeCase{ty_i32, "data.inner.b = value"},
+ TypeCase{ty_vec2<u32>, "data.inner.b = value"},
+ TypeCase{ty_vec2<f32>, "data.inner.b = value"},
+ TypeCase{ty_vec2<i32>, "data.inner.b = value"},
+ TypeCase{ty_vec3<u32>, "data.inner.b = value"},
+ TypeCase{ty_vec3<f32>, "data.inner.b = value"},
+ TypeCase{ty_vec3<i32>, "data.inner.b = value"},
+ TypeCase{ty_vec4<u32>, "data.inner.b = value"},
+ TypeCase{ty_vec4<f32>, "data.inner.b = value"},
+ TypeCase{ty_vec4<i32>, "data.inner.b = value"},
+ TypeCase{ty_mat2x2<f32>, "data.inner.b = value"},
+ TypeCase{ty_mat2x3<f32>, "data.inner.b = value"},
+ TypeCase{ty_mat2x4<f32>, "data.inner.b = value"},
+ TypeCase{ty_mat3x2<f32>, "data.inner.b = value"},
+ TypeCase{ty_mat3x3<f32>, "data.inner.b = value"},
+ TypeCase{ty_mat3x4<f32>, "data.inner.b = value"},
+ TypeCase{ty_mat4x2<f32>, "data.inner.b = value"},
+ TypeCase{ty_mat4x3<f32>, "data.inner.b = value"},
+ TypeCase{ty_mat4x4<f32>, "data.inner.b = value"}));
TEST_F(GlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_Matrix_Empty) {
// struct Data {
@@ -277,16 +277,20 @@
R"(#version 310 es
precision mediump float;
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
int a;
uint pad;
uint pad_1;
uint pad_2;
mat2x3 b;
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
- data.b = mat2x3(vec3(0.0f), vec3(0.0f));
+ data.inner.b = mat2x3(vec3(0.0f), vec3(0.0f));
}
void main() {
@@ -321,16 +325,20 @@
R"(#version 310 es
precision mediump float;
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
float z;
uint pad;
uint pad_1;
uint pad_2;
mat4x3 a;
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
- float x = data.a[2][1];
+ float x = data.inner.a[2][1];
}
void main() {
@@ -365,13 +373,17 @@
R"(#version 310 es
precision mediump float;
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
float z;
int a[5];
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
- int x = data.a[2];
+ int x = data.inner.a[2];
}
void main() {
@@ -409,16 +421,20 @@
R"(#version 310 es
precision mediump float;
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
float z;
int a[5];
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
int a = 2;
int b = 4;
int c = 3;
- int x = data.a[((a + b) - c)];
+ int x = data.inner.a[((a + b) - c)];
}
void main() {
@@ -452,13 +468,17 @@
R"(#version 310 es
precision mediump float;
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
float z;
int a[5];
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
- data.a[2] = 2;
+ data.inner.a[2] = 2;
}
void main() {
@@ -508,12 +528,16 @@
uint pad_1;
};
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
Inner c[4];
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
- vec3 x = data.c[2].b;
+ vec3 x = data.inner.c[2].b;
}
void main() {
@@ -565,12 +589,16 @@
uint pad_1;
};
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
Inner c[4];
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
- vec2 x = data.c[2].b.xy;
+ vec2 x = data.inner.c[2].b.xy;
}
void main() {
@@ -623,12 +651,16 @@
uint pad_1;
};
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
Inner c[4];
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
- float x = data.c[2].b.g;
+ float x = data.inner.c[2].b.g;
}
void main() {
@@ -680,12 +712,16 @@
uint pad_1;
};
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
Inner c[4];
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
- float x = data.c[2].b[1];
+ float x = data.inner.c[2].b[1];
}
void main() {
@@ -736,12 +772,16 @@
uint pad_1;
};
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
Inner c[4];
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
- data.c[2].b = vec3(1.0f, 2.0f, 3.0f);
+ data.inner.c[2].b = vec3(1.0f, 2.0f, 3.0f);
}
void main() {
@@ -793,12 +833,16 @@
uint pad_1;
};
-layout(binding = 0, std430) buffer Data_ssbo {
+struct Data {
Inner c[4];
+};
+
+layout(binding = 0, std430) buffer data_block_ssbo {
+ Data inner;
} data;
void tint_symbol() {
- data.c[2].b.y = 1.0f;
+ data.inner.c[2].b.y = 1.0f;
}
void main() {
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index d9c3479..92e0cc5 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -162,6 +162,7 @@
polyfills.acosh = transform::BuiltinPolyfill::Level::kFull;
polyfills.asinh = true;
polyfills.atanh = transform::BuiltinPolyfill::Level::kFull;
+ polyfills.bitshift_modulo = true;
polyfills.clamp_int = true;
// TODO(crbug.com/tint/1449): Some of these can map to HLSL's `firstbitlow`
// and `firstbithigh`.
@@ -1047,6 +1048,9 @@
if (type == sem::BuiltinType::kRadians) {
return EmitRadiansCall(out, expr, builtin);
}
+ if (type == sem::BuiltinType::kQuantizeToF16) {
+ return EmitQuantizeToF16Call(out, expr, builtin);
+ }
if (builtin->IsDataPacking()) {
return EmitDataPackingCall(out, expr, builtin);
}
@@ -1940,6 +1944,22 @@
});
}
+bool GeneratorImpl::EmitQuantizeToF16Call(std::ostream& out,
+ const ast::CallExpression* expr,
+ const sem::Builtin* builtin) {
+ // Emulate by casting to min16float and back again.
+ std::string width;
+ if (auto* vec = builtin->ReturnType()->As<sem::Vector>()) {
+ width = std::to_string(vec->Width());
+ }
+ out << "float" << width << "(min16float" << width << "(";
+ if (!EmitExpression(out, expr->args[0])) {
+ return false;
+ }
+ out << "))";
+ return true;
+}
+
bool GeneratorImpl::EmitDataPackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Builtin* builtin) {
diff --git a/src/tint/writer/hlsl/generator_impl.h b/src/tint/writer/hlsl/generator_impl.h
index 2742f00..eca7734 100644
--- a/src/tint/writer/hlsl/generator_impl.h
+++ b/src/tint/writer/hlsl/generator_impl.h
@@ -267,6 +267,14 @@
bool EmitDataUnpackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Builtin* builtin);
+ /// Handles generating a call to the `quantizeToF16()` intrinsic
+ /// @param out the output of the expression stream
+ /// @param expr the call expression
+ /// @param builtin the semantic information for the builtin
+ /// @returns true if the call expression is emitted
+ bool EmitQuantizeToF16Call(std::ostream& out,
+ const ast::CallExpression* expr,
+ const sem::Builtin* builtin);
/// Handles generating a call to DP4a builtins (dot4I8Packed and dot4U8Packed)
/// @param out the output of the expression stream
/// @param expr the call expression
diff --git a/src/tint/writer/hlsl/generator_impl_import_test.cc b/src/tint/writer/hlsl/generator_impl_import_test.cc
index e953afb..96ed7ee 100644
--- a/src/tint/writer/hlsl/generator_impl_import_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_import_test.cc
@@ -268,5 +268,31 @@
EXPECT_EQ(out.str(), std::string("determinant(var)"));
}
+TEST_F(HlslGeneratorImplTest_Import, HlslImportData_QuantizeToF16_Scalar) {
+ GlobalVar("v", Expr(2_f), ast::AddressSpace::kPrivate);
+
+ auto* expr = Call("quantizeToF16", "v");
+ WrapInFunction(expr);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
+ EXPECT_EQ(out.str(), std::string("float(min16float(v))"));
+}
+
+TEST_F(HlslGeneratorImplTest_Import, HlslImportData_QuantizeToF16_Vector) {
+ GlobalVar("v", vec3<f32>(2_f), ast::AddressSpace::kPrivate);
+
+ auto* expr = Call("quantizeToF16", "v");
+ WrapInFunction(expr);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
+ EXPECT_EQ(out.str(), std::string("float3(min16float3(v))"));
+}
+
} // namespace
} // namespace tint::writer::hlsl
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc
index 43633b5..65b5275 100644
--- a/src/tint/writer/msl/generator_impl.cc
+++ b/src/tint/writer/msl/generator_impl.cc
@@ -171,6 +171,7 @@
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
+ polyfills.bitshift_modulo = true; // crbug.com/tint/1543
polyfills.clamp_int = true;
polyfills.extract_bits = transform::BuiltinPolyfill::Level::kClampParameters;
polyfills.first_leading_bit = true;
@@ -691,6 +692,18 @@
out << "))";
return true;
}
+ case sem::BuiltinType::kQuantizeToF16: {
+ std::string width = "";
+ if (auto* vec = builtin->ReturnType()->As<sem::Vector>()) {
+ width = std::to_string(vec->Width());
+ }
+ out << "float" << width << "(half" << width << "(";
+ if (!EmitExpression(out, expr->args[0])) {
+ return false;
+ }
+ out << "))";
+ return true;
+ }
// TODO(crbug.com/tint/661): Combine sequential barriers to a single
// instruction.
case sem::BuiltinType::kStorageBarrier: {
diff --git a/src/tint/writer/msl/generator_impl_import_test.cc b/src/tint/writer/msl/generator_impl_import_test.cc
index 4a81130..07f4acd 100644
--- a/src/tint/writer/msl/generator_impl_import_test.cc
+++ b/src/tint/writer/msl/generator_impl_import_test.cc
@@ -247,5 +247,31 @@
EXPECT_EQ(out.str(), std::string("determinant(var)"));
}
+TEST_F(MslGeneratorImplTest, MslImportData_QuantizeToF16_Scalar) {
+ GlobalVar("v", Expr(2_f), ast::AddressSpace::kPrivate);
+
+ auto* expr = Call("quantizeToF16", "v");
+ WrapInFunction(expr);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
+ EXPECT_EQ(out.str(), "float(half(v))");
+}
+
+TEST_F(MslGeneratorImplTest, MslImportData_QuantizeToF16_Vector) {
+ GlobalVar("v", vec3<f32>(2_f), ast::AddressSpace::kPrivate);
+
+ auto* expr = Call("quantizeToF16", "v");
+ WrapInFunction(expr);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitCall(out, expr)) << gen.error();
+ EXPECT_EQ(out.str(), "float3(half3(v))");
+}
+
} // namespace
} // namespace tint::writer::msl
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index 97a29f3..6342f71 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -2505,6 +2505,9 @@
}
return result_id;
}
+ case BuiltinType::kQuantizeToF16:
+ op = spv::Op::OpQuantizeToF16;
+ break;
case BuiltinType::kReverseBits:
op = spv::Op::OpBitReverse;
break;
diff --git a/src/tint/writer/spirv/builder_builtin_test.cc b/src/tint/writer/spirv/builder_builtin_test.cc
index 3c97da7..efdc43b 100644
--- a/src/tint/writer/spirv/builder_builtin_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_test.cc
@@ -1854,6 +1854,105 @@
Validate(b);
}
+TEST_F(BuiltinBuilderTest, Call_QuantizeToF16_Scalar) {
+ GlobalVar("v", Expr(2_f), ast::AddressSpace::kPrivate);
+
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", Call("quantizeToF16", "v"))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+ auto got = DumpBuilder(b);
+ auto* expect = R"(OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %7 "a_func"
+OpExecutionMode %7 OriginUpperLeft
+OpName %3 "v"
+OpName %7 "a_func"
+%1 = OpTypeFloat 32
+%2 = OpConstant %1 2
+%4 = OpTypePointer Private %1
+%3 = OpVariable %4 Private %2
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
+%7 = OpFunction %6 None %5
+%8 = OpLabel
+%10 = OpLoad %1 %3
+%9 = OpQuantizeToF16 %1 %10
+OpReturn
+OpFunctionEnd
+)";
+ EXPECT_EQ(expect, got);
+
+ Validate(b);
+}
+
+TEST_F(BuiltinBuilderTest, Call_QuantizeToF16_Vector) {
+ GlobalVar("v", vec3<f32>(2_f), ast::AddressSpace::kPrivate);
+
+ Func("a_func", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("l", Call("quantizeToF16", "v"))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+ auto got = DumpBuilder(b);
+ auto* expect = R"(OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %24 "a_func"
+OpExecutionMode %24 OriginUpperLeft
+OpName %5 "v"
+OpName %8 "tint_quantizeToF16"
+OpName %9 "v_1"
+OpName %24 "a_func"
+%2 = OpTypeFloat 32
+%1 = OpTypeVector %2 3
+%3 = OpConstant %2 2
+%4 = OpConstantComposite %1 %3 %3 %3
+%6 = OpTypePointer Private %1
+%5 = OpVariable %6 Private %4
+%7 = OpTypeFunction %1 %1
+%12 = OpTypeInt 32 0
+%13 = OpConstantNull %12
+%16 = OpConstant %12 1
+%19 = OpConstant %12 2
+%23 = OpTypeVoid
+%22 = OpTypeFunction %23
+%8 = OpFunction %1 None %7
+%9 = OpFunctionParameter %1
+%10 = OpLabel
+%14 = OpCompositeExtract %2 %9 0
+%11 = OpQuantizeToF16 %2 %14
+%17 = OpCompositeExtract %2 %9 1
+%15 = OpQuantizeToF16 %2 %17
+%20 = OpCompositeExtract %2 %9 2
+%18 = OpQuantizeToF16 %2 %20
+%21 = OpCompositeConstruct %1 %11 %15 %18
+OpReturnValue %21
+OpFunctionEnd
+%24 = OpFunction %23 None %22
+%25 = OpLabel
+%27 = OpLoad %1 %5
+%26 = OpFunctionCall %1 %8 %27
+OpReturn
+OpFunctionEnd
+)";
+ EXPECT_EQ(expect, got);
+
+ Validate(b);
+}
+
} // namespace float_builtin_tests
// Tests for Numeric builtins with all integer parameter
@@ -3241,25 +3340,26 @@
ASSERT_EQ(b.functions().size(), 1_u);
- auto* expected_types = R"(%4 = OpTypeInt 32 0
-%5 = OpTypeInt 32 1
-%3 = OpTypeStruct %4 %5
+ auto* expected_types = R"(%5 = OpTypeInt 32 0
+%6 = OpTypeInt 32 1
+%4 = OpTypeStruct %5 %6
+%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-%11 = OpConstant %4 1
-%12 = OpConstant %4 0
-%14 = OpTypePointer StorageBuffer %4
-%18 = OpTypePointer StorageBuffer %5
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
+%12 = OpConstant %5 1
+%13 = OpConstant %5 0
+%15 = OpTypePointer StorageBuffer %5
+%19 = OpTypePointer StorageBuffer %6
)";
auto got_types = DumpInstructions(b.types());
EXPECT_EQ(expected_types, got_types);
- auto* expected_instructions = R"(%15 = OpAccessChain %14 %1 %12
-%10 = OpAtomicLoad %4 %15 %11 %12
-%19 = OpAccessChain %18 %1 %11
-%16 = OpAtomicLoad %5 %19 %11 %12
+ auto* expected_instructions = R"(%16 = OpAccessChain %15 %1 %13 %13
+%11 = OpAtomicLoad %5 %16 %12 %13
+%20 = OpAccessChain %19 %1 %13 %12
+%17 = OpAtomicLoad %6 %20 %12 %13
OpReturn
)";
auto got_instructions = DumpInstructions(b.functions()[0].instructions());
@@ -3306,34 +3406,35 @@
ASSERT_EQ(b.functions().size(), 1_u);
- auto* expected_types = R"(%4 = OpTypeInt 32 0
-%5 = OpTypeInt 32 1
-%3 = OpTypeStruct %4 %5
+ auto* expected_types = R"(%5 = OpTypeInt 32 0
+%6 = OpTypeInt 32 1
+%4 = OpTypeStruct %5 %6
+%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-%10 = OpConstant %4 1
-%12 = OpTypePointer Function %4
-%13 = OpConstantNull %4
-%14 = OpConstant %5 2
-%16 = OpTypePointer Function %5
-%17 = OpConstantNull %5
-%19 = OpConstant %4 0
-%21 = OpTypePointer StorageBuffer %4
-%26 = OpTypePointer StorageBuffer %5
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
+%11 = OpConstant %5 1
+%13 = OpTypePointer Function %5
+%14 = OpConstantNull %5
+%15 = OpConstant %6 2
+%17 = OpTypePointer Function %6
+%18 = OpConstantNull %6
+%20 = OpConstant %5 0
+%22 = OpTypePointer StorageBuffer %5
+%27 = OpTypePointer StorageBuffer %6
)";
auto got_types = DumpInstructions(b.types());
EXPECT_EQ(expected_types, got_types);
- auto* expected_instructions = R"(OpStore %11 %10
-OpStore %15 %14
-%22 = OpAccessChain %21 %1 %19
-%23 = OpLoad %4 %11
-OpAtomicStore %22 %10 %19 %23
-%27 = OpAccessChain %26 %1 %10
-%28 = OpLoad %5 %15
-OpAtomicStore %27 %10 %19 %28
+ auto* expected_instructions = R"(OpStore %12 %11
+OpStore %16 %15
+%23 = OpAccessChain %22 %1 %20 %20
+%24 = OpLoad %5 %12
+OpAtomicStore %23 %11 %20 %24
+%28 = OpAccessChain %27 %1 %20 %11
+%29 = OpLoad %6 %16
+OpAtomicStore %28 %11 %20 %29
OpReturn
)";
auto got_instructions = DumpInstructions(b.functions()[0].instructions());
@@ -3376,28 +3477,29 @@
ASSERT_EQ(b.functions().size(), 1_u);
- std::string expected_types = R"(%4 = OpTypeInt 32 1
+ std::string expected_types = R"(%5 = OpTypeInt 32 1
+%4 = OpTypeStruct %5
%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
-%9 = OpConstant %4 10
-%11 = OpTypePointer Function %4
-%12 = OpConstantNull %4
-%14 = OpTypeInt 32 0
-%15 = OpConstant %14 1
-%16 = OpConstant %14 0
-%18 = OpTypePointer StorageBuffer %4
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+%10 = OpConstant %5 10
+%12 = OpTypePointer Function %5
+%13 = OpConstantNull %5
+%15 = OpTypeInt 32 0
+%16 = OpConstant %15 1
+%17 = OpConstant %15 0
+%19 = OpTypePointer StorageBuffer %5
)";
auto got_types = DumpInstructions(b.types());
EXPECT_EQ(expected_types, got_types);
- std::string expected_instructions = R"(OpStore %10 %9
-%19 = OpAccessChain %18 %1 %16
-%20 = OpLoad %4 %10
+ std::string expected_instructions = R"(OpStore %11 %10
+%20 = OpAccessChain %19 %1 %17 %17
+%21 = OpLoad %5 %11
)";
- expected_instructions += "%13 = " + GetParam().op + " %4 %19 %15 %16 %20\n";
+ expected_instructions += "%14 = " + GetParam().op + " %5 %20 %16 %17 %21\n";
expected_instructions += "OpReturn\n";
auto got_instructions = DumpInstructions(b.functions()[0].instructions());
@@ -3448,27 +3550,28 @@
ASSERT_EQ(b.functions().size(), 1_u);
- std::string expected_types = R"(%4 = OpTypeInt 32 0
+ std::string expected_types = R"(%5 = OpTypeInt 32 0
+%4 = OpTypeStruct %5
%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
-%9 = OpConstant %4 10
-%11 = OpTypePointer Function %4
-%12 = OpConstantNull %4
-%14 = OpConstant %4 1
-%15 = OpConstant %4 0
-%17 = OpTypePointer StorageBuffer %4
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+%10 = OpConstant %5 10
+%12 = OpTypePointer Function %5
+%13 = OpConstantNull %5
+%15 = OpConstant %5 1
+%16 = OpConstant %5 0
+%18 = OpTypePointer StorageBuffer %5
)";
auto got_types = DumpInstructions(b.types());
EXPECT_EQ(expected_types, got_types);
- std::string expected_instructions = R"(OpStore %10 %9
-%18 = OpAccessChain %17 %1 %15
-%19 = OpLoad %4 %10
+ std::string expected_instructions = R"(OpStore %11 %10
+%19 = OpAccessChain %18 %1 %16 %16
+%20 = OpLoad %5 %11
)";
- expected_instructions += "%13 = " + GetParam().op + " %4 %18 %14 %15 %19\n";
+ expected_instructions += "%14 = " + GetParam().op + " %5 %19 %15 %16 %20\n";
expected_instructions += "OpReturn\n";
auto got_instructions = DumpInstructions(b.functions()[0].instructions());
@@ -3525,35 +3628,36 @@
ASSERT_EQ(b.functions().size(), 1_u);
- auto* expected_types = R"(%4 = OpTypeInt 32 0
-%5 = OpTypeInt 32 1
-%3 = OpTypeStruct %4 %5
+ auto* expected_types = R"(%5 = OpTypeInt 32 0
+%6 = OpTypeInt 32 1
+%4 = OpTypeStruct %5 %6
+%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-%10 = OpConstant %4 10
-%12 = OpTypePointer Function %4
-%13 = OpConstantNull %4
-%14 = OpConstant %5 10
-%16 = OpTypePointer Function %5
-%17 = OpConstantNull %5
-%19 = OpConstant %4 1
-%20 = OpConstant %4 0
-%22 = OpTypePointer StorageBuffer %4
-%27 = OpTypePointer StorageBuffer %5
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
+%11 = OpConstant %5 10
+%13 = OpTypePointer Function %5
+%14 = OpConstantNull %5
+%15 = OpConstant %6 10
+%17 = OpTypePointer Function %6
+%18 = OpConstantNull %6
+%20 = OpConstant %5 1
+%21 = OpConstant %5 0
+%23 = OpTypePointer StorageBuffer %5
+%28 = OpTypePointer StorageBuffer %6
)";
auto got_types = DumpInstructions(b.types());
EXPECT_EQ(expected_types, got_types);
- auto* expected_instructions = R"(OpStore %11 %10
-OpStore %15 %14
-%23 = OpAccessChain %22 %1 %20
-%24 = OpLoad %4 %11
-%18 = OpAtomicExchange %4 %23 %19 %20 %24
-%28 = OpAccessChain %27 %1 %19
-%29 = OpLoad %5 %15
-%25 = OpAtomicExchange %5 %28 %19 %20 %29
+ auto* expected_instructions = R"(OpStore %12 %11
+OpStore %16 %15
+%24 = OpAccessChain %23 %1 %21 %21
+%25 = OpLoad %5 %12
+%19 = OpAtomicExchange %5 %24 %20 %21 %25
+%29 = OpAccessChain %28 %1 %21 %20
+%30 = OpLoad %6 %16
+%26 = OpAtomicExchange %6 %29 %20 %21 %30
OpReturn
)";
auto got_instructions = DumpInstructions(b.functions()[0].instructions());
@@ -3598,36 +3702,37 @@
ASSERT_EQ(b.functions().size(), 1_u);
- auto* expected_types = R"(%4 = OpTypeInt 32 0
-%5 = OpTypeInt 32 1
-%3 = OpTypeStruct %4 %5
+ auto* expected_types = R"(%5 = OpTypeInt 32 0
+%6 = OpTypeInt 32 1
+%4 = OpTypeStruct %5 %6
+%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
-%12 = OpTypeBool
-%11 = OpTypeStruct %4 %12
-%13 = OpConstant %4 1
-%14 = OpConstant %4 0
-%16 = OpTypePointer StorageBuffer %4
-%18 = OpConstant %4 20
-%19 = OpConstant %4 10
-%23 = OpTypeStruct %5 %12
-%25 = OpTypePointer StorageBuffer %5
-%27 = OpConstant %5 20
-%28 = OpConstant %5 10
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
+%13 = OpTypeBool
+%12 = OpTypeStruct %5 %13
+%14 = OpConstant %5 1
+%15 = OpConstant %5 0
+%17 = OpTypePointer StorageBuffer %5
+%19 = OpConstant %5 20
+%20 = OpConstant %5 10
+%24 = OpTypeStruct %6 %13
+%26 = OpTypePointer StorageBuffer %6
+%28 = OpConstant %6 20
+%29 = OpConstant %6 10
)";
auto got_types = DumpInstructions(b.types());
EXPECT_EQ(expected_types, got_types);
- auto* expected_instructions = R"(%17 = OpAccessChain %16 %1 %14
-%20 = OpAtomicCompareExchange %4 %17 %13 %14 %14 %18 %19
-%21 = OpIEqual %12 %20 %19
-%10 = OpCompositeConstruct %11 %20 %21
-%26 = OpAccessChain %25 %1 %13
-%29 = OpAtomicCompareExchange %5 %26 %13 %14 %14 %27 %28
-%30 = OpIEqual %12 %29 %28
-%22 = OpCompositeConstruct %23 %29 %30
+ auto* expected_instructions = R"(%18 = OpAccessChain %17 %1 %15 %15
+%21 = OpAtomicCompareExchange %5 %18 %14 %15 %15 %19 %20
+%22 = OpIEqual %13 %21 %20
+%11 = OpCompositeConstruct %12 %21 %22
+%27 = OpAccessChain %26 %1 %15 %14
+%30 = OpAtomicCompareExchange %6 %27 %14 %15 %15 %28 %29
+%31 = OpIEqual %13 %30 %29
+%23 = OpCompositeConstruct %24 %30 %31
OpReturn
)";
auto got_instructions = DumpInstructions(b.functions()[0].instructions());
diff --git a/src/tint/writer/spirv/builder_function_test.cc b/src/tint/writer/spirv/builder_function_test.cc
index b28817c..efaefed 100644
--- a/src/tint/writer/spirv/builder_function_test.cc
+++ b/src/tint/writer/spirv/builder_function_test.cc
@@ -228,46 +228,50 @@
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader
OpMemoryModel Logical GLSL450
-OpEntryPoint GLCompute %7 "a"
-OpEntryPoint GLCompute %17 "b"
-OpExecutionMode %7 LocalSize 1 1 1
-OpExecutionMode %17 LocalSize 1 1 1
-OpName %3 "Data"
-OpMemberName %3 0 "d"
+OpEntryPoint GLCompute %8 "a"
+OpEntryPoint GLCompute %18 "b"
+OpExecutionMode %8 LocalSize 1 1 1
+OpExecutionMode %18 LocalSize 1 1 1
+OpName %3 "data_block"
+OpMemberName %3 0 "inner"
+OpName %4 "Data"
+OpMemberName %4 0 "d"
OpName %1 "data"
-OpName %7 "a"
-OpName %14 "v"
-OpName %17 "b"
-OpName %21 "v"
+OpName %8 "a"
+OpName %15 "v"
+OpName %18 "b"
+OpName %22 "v"
OpDecorate %3 Block
OpMemberDecorate %3 0 Offset 0
+OpMemberDecorate %4 0 Offset 0
OpDecorate %1 Binding 0
OpDecorate %1 DescriptorSet 0
-%4 = OpTypeFloat 32
+%5 = OpTypeFloat 32
+%4 = OpTypeStruct %5
%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
-%9 = OpTypeInt 32 0
-%10 = OpConstant %9 0
-%11 = OpTypePointer StorageBuffer %4
-%15 = OpTypePointer Function %4
-%16 = OpConstantNull %4
-%7 = OpFunction %6 None %5
-%8 = OpLabel
-%14 = OpVariable %15 Function %16
-%12 = OpAccessChain %11 %1 %10
-%13 = OpLoad %4 %12
-OpStore %14 %13
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
+%10 = OpTypeInt 32 0
+%11 = OpConstant %10 0
+%12 = OpTypePointer StorageBuffer %5
+%16 = OpTypePointer Function %5
+%17 = OpConstantNull %5
+%8 = OpFunction %7 None %6
+%9 = OpLabel
+%15 = OpVariable %16 Function %17
+%13 = OpAccessChain %12 %1 %11 %11
+%14 = OpLoad %5 %13
+OpStore %15 %14
OpReturn
OpFunctionEnd
-%17 = OpFunction %6 None %5
-%18 = OpLabel
-%21 = OpVariable %15 Function %16
-%19 = OpAccessChain %11 %1 %10
-%20 = OpLoad %4 %19
-OpStore %21 %20
+%18 = OpFunction %7 None %6
+%19 = OpLabel
+%22 = OpVariable %16 Function %17
+%20 = OpAccessChain %12 %1 %11 %11
+%21 = OpLoad %5 %20
+OpStore %22 %21
OpReturn
OpFunctionEnd
)");
diff --git a/src/tint/writer/spirv/builder_global_variable_test.cc b/src/tint/writer/spirv/builder_global_variable_test.cc
index 64eac22..7d3ec59 100644
--- a/src/tint/writer/spirv/builder_global_variable_test.cc
+++ b/src/tint/writer/spirv/builder_global_variable_test.cc
@@ -316,23 +316,27 @@
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %3 Block
OpMemberDecorate %3 0 Offset 0
-OpMemberDecorate %3 1 Offset 4
+OpMemberDecorate %4 0 Offset 0
+OpMemberDecorate %4 1 Offset 4
OpDecorate %1 NonWritable
OpDecorate %1 Binding 0
OpDecorate %1 DescriptorSet 0
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "A"
-OpMemberName %3 0 "a"
-OpMemberName %3 1 "b"
+ EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+OpMemberName %3 0 "inner"
+OpName %4 "A"
+OpMemberName %4 0 "a"
+OpMemberName %4 1 "b"
OpName %1 "b"
-OpName %7 "unused_entry_point"
+OpName %8 "unused_entry_point"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
-%3 = OpTypeStruct %4 %4
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+%4 = OpTypeStruct %5 %5
+%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
)");
}
@@ -354,21 +358,25 @@
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %3 Block
OpMemberDecorate %3 0 Offset 0
+OpMemberDecorate %4 0 Offset 0
OpDecorate %1 NonWritable
OpDecorate %1 Binding 0
OpDecorate %1 DescriptorSet 0
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "A"
-OpMemberName %3 0 "a"
+ EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+OpMemberName %3 0 "inner"
+OpName %4 "A"
+OpMemberName %4 0 "a"
OpName %1 "b"
-OpName %7 "unused_entry_point"
+OpName %8 "unused_entry_point"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+%4 = OpTypeStruct %5
%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
)");
}
@@ -390,21 +398,25 @@
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %3 Block
OpMemberDecorate %3 0 Offset 0
+OpMemberDecorate %4 0 Offset 0
OpDecorate %1 NonWritable
OpDecorate %1 Binding 0
OpDecorate %1 DescriptorSet 0
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "A"
-OpMemberName %3 0 "a"
+ EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+OpMemberName %3 0 "inner"
+OpName %4 "A"
+OpMemberName %4 0 "a"
OpName %1 "b"
-OpName %7 "unused_entry_point"
+OpName %8 "unused_entry_point"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+%4 = OpTypeStruct %5
%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
+%7 = OpTypeVoid
+%6 = OpTypeFunction %7
)");
}
@@ -428,25 +440,29 @@
EXPECT_EQ(DumpInstructions(b.annots()),
R"(OpDecorate %3 Block
OpMemberDecorate %3 0 Offset 0
+OpMemberDecorate %4 0 Offset 0
OpDecorate %1 NonWritable
OpDecorate %1 DescriptorSet 0
OpDecorate %1 Binding 0
-OpDecorate %5 DescriptorSet 1
-OpDecorate %5 Binding 0
+OpDecorate %6 DescriptorSet 1
+OpDecorate %6 Binding 0
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "A"
-OpMemberName %3 0 "a"
+ EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+OpMemberName %3 0 "inner"
+OpName %4 "A"
+OpMemberName %4 0 "a"
OpName %1 "b"
-OpName %5 "c"
-OpName %8 "unused_entry_point"
+OpName %6 "c"
+OpName %9 "unused_entry_point"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+%4 = OpTypeStruct %5
%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
%1 = OpVariable %2 StorageBuffer
-%5 = OpVariable %2 StorageBuffer
-%7 = OpTypeVoid
-%6 = OpTypeFunction %7
+%6 = OpVariable %2 StorageBuffer
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
)");
}
diff --git a/src/tint/writer/spirv/generator_impl.cc b/src/tint/writer/spirv/generator_impl.cc
index f75f1f2..aa5d449 100644
--- a/src/tint/writer/spirv/generator_impl.cc
+++ b/src/tint/writer/spirv/generator_impl.cc
@@ -52,6 +52,7 @@
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
+ polyfills.bitshift_modulo = true;
polyfills.clamp_int = true;
polyfills.count_leading_zeros = true;
polyfills.count_trailing_zeros = true;
@@ -61,6 +62,7 @@
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters;
polyfills.saturate = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
+ polyfills.quantize_to_vec_f16 = true; // crbug.com/tint/1741
data.Add<transform::BuiltinPolyfill::Config>(polyfills);
manager.Add<transform::BuiltinPolyfill>();
}
diff --git a/tint_overrides_with_defaults.gni b/tint_overrides_with_defaults.gni
index 9680e35..9e39248 100644
--- a/tint_overrides_with_defaults.gni
+++ b/tint_overrides_with_defaults.gni
@@ -71,4 +71,9 @@
if (!defined(tint_build_glsl_writer)) {
tint_build_glsl_writer = true
}
+
+ # Build unittests
+ if (!defined(tint_build_unittests)) {
+ tint_build_unittests = true
+ }
}