Import Tint changes from Dawn
Changes:
- c0d51f1cd8945d035ed9ff83bd37d89cbf7e3de2 tint: spirv reader: detect and replace loads and stores o... by Antonio Maiorano <amaiorano@google.com>
- c7d6ab6c5af7b3da8665ebac74408d9d5dcbd96d tint: Prevent function calls at module-scope by Ben Clayton <bclayton@google.com>
- aa037ac489cde4ae1ec289e7927821c89d6c579d tint: Refactor sem::Constant to be less memory-hungry by Ben Clayton <bclayton@google.com>
- cf52af7b0f2d5bf7764ff9c3840c1ac38fb1ccb9 tint: Have Number equality consider sign by Ben Clayton <bclayton@google.com>
- 3a2a27971487769c4581c876ea379854a4fe997a Fixup various warnings in Tint which were accidentally su... by dan sinclair <dsinclair@chromium.org>
- 2b4df7889186d2e98e437a2d1bb3e083b4722edb tint/number: Fix CheckedConvert() logic by Ben Clayton <bclayton@google.com>
- 72876c14c3dc5fb947da619ef1fbb4faa9e98a3e tint/sem/constant.h: Remove #include to program_builder.h by Ben Clayton <bclayton@google.com>
- c64ca23d94aae25c5573bb4ad354a8686fba285c tint: Deprecated module-scope 'let' for 'const' by Ben Clayton <bclayton@google.com>
- d23f296a9a31daa764d348169d3ae13d5a09877b tint: Implement acosh, asinh, atanh by dan sinclair <dsinclair@chromium.org>
- 6058882d4bf54d47d79ad528561ac89f66ec199a tint/resolver: Add f16 types, constructor, and conversions by Zhaoming Jiang <zhaoming.jiang@intel.com>
- 53af15836660ebd851702ebc1551dca0d0447249 tint/reader: Allow module-scope 'var' type inferencing by Ben Clayton <bclayton@google.com>
- 19576e9015d2b2ce7a1933ec14606748a6902ead tint/writer: Handle and emit 'const' variables by Ben Clayton <bclayton@google.com>
- 6c167a0dc78380dfc5d60623aa435af80066b910 msl: Promote local private vars to function scope by dan sinclair <dsinclair@chromium.org>
- 7ebcfc7e0e2ad76202a77325d1e8dd82322c5d2a tint/transform: PromoteInitializersToLet by Ben Clayton <bclayton@google.com>
- ce466c0df3d8474e61dff2315aa8de1c722d82eb tint: spir-v writer: Fix matrix constructor from matrix v... by Antonio Maiorano <amaiorano@google.com>
- 54b3da95f808f14b913cbfe8132e7977246f443b tint/transform: Handle 'const' for Unshadow. by Ben Clayton <bclayton@google.com>
- fcf9fdcad813691915fc313a7a1af1bbf3d9523f tint/writer/wgsl: Emit 'const' variables by Ben Clayton <bclayton@google.com>
- f90313396b63da549e8c535aaa577d9fe1dea5a1 tint/reader/wgsl: Drop const_expr parsing by Ben Clayton <bclayton@google.com>
- e48ef8ef9070c319c0a3beb372076948c2131437 tint/reader: Enable 'const' parsing for unit-tests by Ben Clayton <bclayton@google.com>
- 511529f082daa0ae7f803024dfbce1ba1e0e9fe3 tint/resolver: Clean up workgroup-size error diagnostic by Ben Clayton <bclayton@google.com>
- 410a3bd19a06889017740633b5cf421d70ccf664 tint/resolver: Propagate constant values between 'const's by Ben Clayton <bclayton@google.com>
- e3834c47604ebccf4337604612eec1f51411a7bb tint/resolver: Resolve 'const' variables by Ben Clayton <bclayton@google.com>
- 01208e7e42ae6c56b4fdb2618ff72e91708a2206 tint: Rename Global() -> GlobalVar() by Ben Clayton <bclayton@google.com>
- 41486e11350217e4e50480411305889384beff4f tint: Rename GlobalConst() -> GlobalLet() by Ben Clayton <bclayton@google.com>
- b4ff8c859a26e8ac060062198cfaf35d6b8c4520 tint/resolver: Simplify array size evaluation by Ben Clayton <bclayton@google.com>
- 268d7b83571ae65b7e59a6df251ecb6ac0f5a806 tint: Add support for atomic ops to spirv reader by Antonio Maiorano <amaiorano@google.com>
- ebed939759cb7b6fc9725e9430093166d7e7c21b tint/resolver: Tidy up variable_test.cc by Ben Clayton <bclayton@google.com>
- 68ae36e43d1e7b6d8138bb1a794b2d3614a31f6e tint/resolver: Rename var_let_*test.cc -> variable_*test.cc by Ben Clayton <bclayton@google.com>
- dfeaf29055e17d1a01caa7c69af50e577808cfda tint: Add sem::IndexAccessorExpression by Antonio Maiorano <amaiorano@google.com>
- 32cb9cf2f8ae5937c3ad45de39cb0638309502fd tint/writer: Disable constant inlining for lets by Ben Clayton <bclayton@google.com>
- c5f7e8f0bc9983a9010c5353932601b40bd45ae7 tint: Fix emitting identity matrix ctor in HLSL by Zhaoming Jiang <zhaoming.jiang@intel.com>
- f47887d2073504bf13152ff5ae142a6653ba322c tint/writer/msl: Generate an array<T,N> helper by Ben Clayton <bclayton@google.com>
- 3c054304a8fc579ea085d44af010e470cb591921 tint/sem: Support arrays for sem::Constant by Ben Clayton <bclayton@google.com>
- e8d47d52636e9499915422a53ccde978b24feb02 tint/sem: Add more checks to constant_test.cc by Ben Clayton <bclayton@google.com>
- ab70ff7a2fc355defd4558aeb75914e10f5f3610 tint/writer/spirv: Clean up accessor tests by Ben Clayton <bclayton@google.com>
- 3a68ab4a1718e6eb23d21d2eb4d0db14ecdf4b6d tint/writer: Minor generator cleanup. by Ben Clayton <bclayton@google.com>
- 50414807150bdac9f41817fea7bdf939425768be tint/writer: Clean up EmitConstant() methods by Ben Clayton <bclayton@google.com>
- 18b966321bca9ed2a7787c0adbbb18d013fac43e tint: remove duplicated ending newline in ctor_conv_intri... by Zhaoming Jiang <zhaoming.jiang@intel.com>
- c1cb9dc1a5c038ad2d3bad0edc852688f638d9ac tint/resolver: Evaluate constant index accessors by Ben Clayton <bclayton@google.com>
- f99671b830811d33dc1d1e234c4b66300ed007a7 tint: spir-v reader: fix atomicCompareExchangeWeak with v... by Antonio Maiorano <amaiorano@google.com>
- 77bf233cef236a094ef845d8f1a31073c2ddd7b9 Move tint unittest behind a build flag. by dan sinclair <dsinclair@chromium.org>
- 1ed376be34219ad52892fcb3b83787cfc026e9b4 tint/sem: Add range overload of Constant::AllZero() by Ben Clayton <bclayton@google.com>
- ef62b58cf96ea4d0f0f22fac1d0c768e15aab00c Skip Gamma and Gamut conversions for BT.709->SRGB by jchen10 <jie.a.chen@intel.com>
- 797f0f82e0521a4aaaad3004dc281df6581c693e tint/sem: Return vector for Type::ElementOf(matrix) by Ben Clayton <bclayton@google.com>
- 44eb10814e2aa8b07c96573bd268cf2ea15d97b7 tint/resolver: Change return type of EvaluateConstantValu... by Ben Clayton <bclayton@google.com>
- e021566617d6c705387c4faf4f95f1501995845a tint/reader/wgsl: Lex 'const' by Ben Clayton <bclayton@google.com>
- 3b3ef3624120551e2599c6a02bee1e8de3b01b0f tint/sem: Add Type::DeepestElementOf() by Ben Clayton <bclayton@google.com>
- 7ee324551c65bff676039448b1440ff6646ef9c0 tint/ast: Add 'const' AST node by Ben Clayton <bclayton@google.com>
- 42fdeb2c8cf26a18c2bf7687cbe492a8ae46e3e5 Remove test/tint/BUILD.gn by dan sinclair <dsinclair@chromium.org>
- 22d8dea091662c05e0ec510e0d67995cd2153618 tint/resolver: Fix ICE when failing to materialize by Ben Clayton <bclayton@google.com>
- e4e4854b77c3bce27996d86cbcfbed0b158397df tint/resolver: Clean up 'let' / 'override' resolving by Ben Clayton <bclayton@google.com>
- ee49b1ed9550b8a8a0018ea51d76613b2dd5a5e4 tint/resolver: Clean up 'var' resolving by Ben Clayton <bclayton@google.com>
- 80fdd624a0919ed5578a3e8c1c0b18b3d347e1b4 tint: Process functions in dependency order by James Price <jrprice@google.com>
- 46583621c0b17e72da334b2471898104e101406c tint: Refactor ModuleScopeVarToEntryPointParam by James Price <jrprice@google.com>
GitOrigin-RevId: c0d51f1cd8945d035ed9ff83bd37d89cbf7e3de2
Change-Id: I772e94e59da83e6466a1694a708186bdc03119ff
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/95260
Reviewed-by: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index f73c1da..09d87d7 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -17,8 +17,8 @@
testonly = true
deps = [
"src/tint:libtint",
+ "src/tint:tint_unittests",
"src/tint/cmd:tint",
"src/tint/fuzzers",
- "test/tint:tint_unittests",
]
}
diff --git a/build_overrides/tint.gni b/build_overrides/tint.gni
index fdcc866..a4594f2 100644
--- a/build_overrides/tint.gni
+++ b/build_overrides/tint.gni
@@ -13,3 +13,4 @@
# limitations under the License.
# This file contains Tint-related overrides.
+tint_build_unittests = true
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 4f17ae2..fb51327 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -13,9 +13,13 @@
# limitations under the License.
import("//build_overrides/build.gni")
-import("//testing/test.gni")
+
import("../../tint_overrides_with_defaults.gni")
+if (tint_build_unittests) {
+ import("//testing/test.gni")
+}
+
###############################################################################
# Common - Configs, etc. shared across targets
###############################################################################
@@ -213,6 +217,8 @@
"ast/case_statement.h",
"ast/compound_assignment_statement.cc",
"ast/compound_assignment_statement.h",
+ "ast/const.cc",
+ "ast/const.h",
"ast/continue_statement.cc",
"ast/continue_statement.h",
"ast/depth_multisampled_texture.cc",
@@ -422,6 +428,7 @@
"sem/for_loop_statement.h",
"sem/i32.h",
"sem/if_statement.h",
+ "sem/index_accessor_expression.h",
"sem/info.h",
"sem/loop_statement.h",
"sem/materialize.h",
@@ -501,8 +508,8 @@
"transform/multiplanar_external_texture.h",
"transform/num_workgroups_from_uniform.cc",
"transform/num_workgroups_from_uniform.h",
- "transform/promote_initializers_to_const_var.cc",
- "transform/promote_initializers_to_const_var.h",
+ "transform/promote_initializers_to_let.cc",
+ "transform/promote_initializers_to_let.h",
"transform/promote_side_effects_to_decl.cc",
"transform/promote_side_effects_to_decl.h",
"transform/remove_continue_in_switch.cc",
@@ -519,6 +526,8 @@
"transform/simplify_pointers.h",
"transform/single_entry_point.cc",
"transform/single_entry_point.h",
+ "transform/spirv_atomic.cc",
+ "transform/spirv_atomic.h",
"transform/transform.cc",
"transform/transform.h",
"transform/unshadow.cc",
@@ -537,8 +546,6 @@
"transform/vertex_pulling.h",
"transform/while_to_loop.cc",
"transform/while_to_loop.h",
- "transform/wrap_arrays_in_structs.cc",
- "transform/wrap_arrays_in_structs.h",
"transform/zero_init_workgroup_memory.cc",
"transform/zero_init_workgroup_memory.h",
"utils/bitcast.h",
@@ -630,6 +637,8 @@
"sem/i32.h",
"sem/if_statement.cc",
"sem/if_statement.h",
+ "sem/index_accessor_expression.cc",
+ "sem/index_accessor_expression.h",
"sem/info.cc",
"sem/info.h",
"sem/loop_statement.cc",
@@ -847,820 +856,820 @@
}
}
-###############################################################################
-# Gtest Gmock - Handle building inside and outside of Chromium.
-###############################################################################
-# When building outside of Chromium we need to define our own targets for GTest
-# and GMock. However when compiling inside of Chromium we need to reuse the
-# existing targets, both because Chromium has a special harness for swarming
-# and because otherwise the "gn check" fails.
+if (tint_build_unittests) {
+ ###############################################################################
+ # Gtest Gmock - Handle building inside and outside of Chromium.
+ ###############################################################################
+ # When building outside of Chromium we need to define our own targets for GTest
+ # and GMock. However when compiling inside of Chromium we need to reuse the
+ # existing targets, both because Chromium has a special harness for swarming
+ # and because otherwise the "gn check" fails.
-if (!build_with_chromium) {
- # When we aren't in Chromium we define out own targets based on the location
- # of the googletest repo.
- config("gtest_config") {
- include_dirs = [
- "${tint_googletest_dir}/googletest",
- "${tint_googletest_dir}/googletest/include",
- ]
+ if (!build_with_chromium) {
+ # When we aren't in Chromium we define out own targets based on the location
+ # of the googletest repo.
+ config("gtest_config") {
+ include_dirs = [
+ "${tint_googletest_dir}/googletest",
+ "${tint_googletest_dir}/googletest/include",
+ ]
+ }
+ static_library("gtest") {
+ testonly = true
+ sources = [ "${tint_googletest_dir}/googletest/src/gtest-all.cc" ]
+ public_configs = [ ":gtest_config" ]
+ }
+
+ config("gmock_config") {
+ include_dirs = [
+ "${tint_googletest_dir}/googlemock",
+ "${tint_googletest_dir}/googlemock/include",
+ "${tint_googletest_dir}/googletest/include",
+ ]
+ }
+
+ static_library("gmock") {
+ testonly = true
+ sources = [ "${tint_googletest_dir}/googlemock/src/gmock-all.cc" ]
+ public_configs = [ ":gmock_config" ]
+ }
+
+ group("gmock_and_gtest") {
+ testonly = true
+ public_deps = [
+ ":gmock",
+ ":gtest",
+ ]
+ }
+ } else {
+ # When we are in Chromium we reuse its targets, and also add some deps that
+ # are needed to launch the test in swarming mode.
+ group("gmock_and_gtest") {
+ testonly = true
+ public_deps = [
+ "//base",
+ "//base/test:test_support",
+ "//testing/gmock",
+ "//testing/gtest",
+ "//third_party/googletest:gmock",
+ ]
+ }
}
- static_library("gtest") {
+
+ ###############################################################################
+ # Wrapping of Chromium targets
+ ###############################################################################
+ # These targets are separated because they are Chromium sources files that
+ # can't use the tint_internal config, otherwise Tint's warning flags get
+ # applied while compiling a bunch of Chromium's //base (via header inclusion)
+ source_set("tint_unittests_main") {
testonly = true
- sources = [ "${tint_googletest_dir}/googletest/src/gtest-all.cc" ]
- public_configs = [ ":gtest_config" ]
+ deps = [ ":gmock_and_gtest" ]
+ if (build_with_chromium) {
+ sources = [ "//gpu/tint_unittests_main.cc" ]
+ } else {
+ sources = [ "test_main.cc" ]
+ configs += [ ":tint_unittests_config" ]
+ deps += [
+ ":libtint",
+ ":tint_unittests_hlsl_writer_src",
+ ":tint_unittests_msl_writer_src",
+ ":tint_unittests_spv_reader_src",
+ ]
+ }
}
- config("gmock_config") {
+ ###############################################################################
+ # Tests - For libtint core and optional modules
+ ###############################################################################
+ config("tint_unittests_config") {
include_dirs = [
- "${tint_googletest_dir}/googlemock",
"${tint_googletest_dir}/googlemock/include",
"${tint_googletest_dir}/googletest/include",
]
- }
- static_library("gmock") {
- testonly = true
- sources = [ "${tint_googletest_dir}/googlemock/src/gmock-all.cc" ]
- public_configs = [ ":gmock_config" ]
- }
-
- group("gmock_and_gtest") {
- testonly = true
- public_deps = [
- ":gmock",
- ":gtest",
+ configs = [
+ ":tint_common_config",
+ ":tint_public_config",
]
}
-} else {
- # When we are in Chromium we reuse its targets, and also add some deps that
- # are needed to launch the test in swarming mode.
- group("gmock_and_gtest") {
- testonly = true
- public_deps = [
- "//base",
- "//base/test:test_support",
- "//testing/gmock",
- "//testing/gtest",
- "//third_party/googletest:gmock",
- ]
- }
-}
-###############################################################################
-# Wrapping of Chromium targets
-###############################################################################
-# These targets are separated because they are Chromium sources files that
-# can't use the tint_internal config, otherwise Tint's warning flags get
-# applied while compiling a bunch of Chromium's //base (via header inclusion)
-source_set("tint_unittests_main") {
- testonly = true
- deps = [ ":gmock_and_gtest" ]
- if (build_with_chromium) {
- sources = [ "//gpu/tint_unittests_main.cc" ]
- } else {
- sources = [ "test_main.cc" ]
- configs += [ ":tint_unittests_config" ]
- deps += [
- ":libtint",
- ":tint_unittests_hlsl_writer_src",
- ":tint_unittests_msl_writer_src",
- ":tint_unittests_spv_reader_src",
- ]
- }
-}
+ template("tint_unittests_source_set") {
+ source_set(target_name) {
+ forward_variables_from(invoker, "*", [ "configs" ])
-###############################################################################
-# Tests - For libtint core and optional modules
-###############################################################################
-config("tint_unittests_config") {
- include_dirs = [
- "${tint_googletest_dir}/googlemock/include",
- "${tint_googletest_dir}/googletest/include",
- ]
+ if (defined(invoker.configs)) {
+ configs += invoker.configs
+ }
+ configs += [ ":tint_unittests_config" ]
+ if (build_with_chromium) {
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [ "//build/config/compiler:no_chromium_code" ]
+ }
- configs = [
- ":tint_common_config",
- ":tint_public_config",
- ]
-}
+ testonly = true
-template("tint_unittests_source_set") {
- source_set(target_name) {
- forward_variables_from(invoker, "*", [ "configs" ])
-
- if (defined(invoker.configs)) {
- configs += invoker.configs
+ if (!defined(invoker.deps)) {
+ deps = []
+ }
+ deps += [
+ ":gmock_and_gtest",
+ ":libtint",
+ ":tint_utils_io",
+ ]
}
+ }
+
+ tint_unittests_source_set("tint_unittests_ast_src") {
+ sources = [
+ "ast/alias_test.cc",
+ "ast/array_test.cc",
+ "ast/assignment_statement_test.cc",
+ "ast/atomic_test.cc",
+ "ast/binary_expression_test.cc",
+ "ast/binding_attribute_test.cc",
+ "ast/bitcast_expression_test.cc",
+ "ast/block_statement_test.cc",
+ "ast/bool_literal_expression_test.cc",
+ "ast/bool_test.cc",
+ "ast/break_statement_test.cc",
+ "ast/builtin_attribute_test.cc",
+ "ast/builtin_texture_helper_test.cc",
+ "ast/builtin_texture_helper_test.h",
+ "ast/call_expression_test.cc",
+ "ast/call_statement_test.cc",
+ "ast/case_statement_test.cc",
+ "ast/compound_assignment_statement_test.cc",
+ "ast/continue_statement_test.cc",
+ "ast/depth_multisampled_texture_test.cc",
+ "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",
+ "ast/fallthrough_statement_test.cc",
+ "ast/float_literal_expression_test.cc",
+ "ast/for_loop_statement_test.cc",
+ "ast/function_test.cc",
+ "ast/group_attribute_test.cc",
+ "ast/i32_test.cc",
+ "ast/id_attribute_test.cc",
+ "ast/identifier_expression_test.cc",
+ "ast/if_statement_test.cc",
+ "ast/increment_decrement_statement_test.cc",
+ "ast/index_accessor_expression_test.cc",
+ "ast/int_literal_expression_test.cc",
+ "ast/interpolate_attribute_test.cc",
+ "ast/invariant_attribute_test.cc",
+ "ast/location_attribute_test.cc",
+ "ast/loop_statement_test.cc",
+ "ast/matrix_test.cc",
+ "ast/member_accessor_expression_test.cc",
+ "ast/module_clone_test.cc",
+ "ast/module_test.cc",
+ "ast/multisampled_texture_test.cc",
+ "ast/phony_expression_test.cc",
+ "ast/pointer_test.cc",
+ "ast/return_statement_test.cc",
+ "ast/sampled_texture_test.cc",
+ "ast/sampler_test.cc",
+ "ast/stage_attribute_test.cc",
+ "ast/storage_texture_test.cc",
+ "ast/stride_attribute_test.cc",
+ "ast/struct_member_align_attribute_test.cc",
+ "ast/struct_member_offset_attribute_test.cc",
+ "ast/struct_member_size_attribute_test.cc",
+ "ast/struct_member_test.cc",
+ "ast/struct_test.cc",
+ "ast/switch_statement_test.cc",
+ "ast/test_helper.h",
+ "ast/texture_test.cc",
+ "ast/traverse_expressions_test.cc",
+ "ast/u32_test.cc",
+ "ast/unary_op_expression_test.cc",
+ "ast/variable_decl_statement_test.cc",
+ "ast/variable_test.cc",
+ "ast/vector_test.cc",
+ "ast/while_statement_test.cc",
+ "ast/workgroup_attribute_test.cc",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_diagnostic_src") {
+ sources = [
+ "diagnostic/diagnostic_test.cc",
+ "diagnostic/formatter_test.cc",
+ "diagnostic/printer_test.cc",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_inspector_src") {
+ sources = [
+ "inspector/inspector_test.cc",
+ "inspector/test_inspector_builder.cc",
+ "inspector/test_inspector_builder.h",
+ "inspector/test_inspector_runner.cc",
+ "inspector/test_inspector_runner.h",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_resolver_src") {
+ sources = [
+ "resolver/array_accessor_test.cc",
+ "resolver/assignment_validation_test.cc",
+ "resolver/atomics_test.cc",
+ "resolver/atomics_validation_test.cc",
+ "resolver/attribute_validation_test.cc",
+ "resolver/bitcast_validation_test.cc",
+ "resolver/builtin_test.cc",
+ "resolver/builtin_validation_test.cc",
+ "resolver/builtins_validation_test.cc",
+ "resolver/call_test.cc",
+ "resolver/call_validation_test.cc",
+ "resolver/compound_assignment_validation_test.cc",
+ "resolver/compound_statement_test.cc",
+ "resolver/control_block_validation_test.cc",
+ "resolver/dependency_graph_test.cc",
+ "resolver/entry_point_validation_test.cc",
+ "resolver/function_validation_test.cc",
+ "resolver/host_shareable_validation_test.cc",
+ "resolver/increment_decrement_validation_test.cc",
+ "resolver/intrinsic_table_test.cc",
+ "resolver/is_host_shareable_test.cc",
+ "resolver/is_storeable_test.cc",
+ "resolver/materialize_test.cc",
+ "resolver/pipeline_overridable_constant_test.cc",
+ "resolver/ptr_ref_test.cc",
+ "resolver/ptr_ref_validation_test.cc",
+ "resolver/resolver_behavior_test.cc",
+ "resolver/resolver_constants_test.cc",
+ "resolver/resolver_test.cc",
+ "resolver/resolver_test_helper.cc",
+ "resolver/resolver_test_helper.h",
+ "resolver/side_effects_test.cc",
+ "resolver/source_variable_test.cc",
+ "resolver/storage_class_layout_validation_test.cc",
+ "resolver/storage_class_validation_test.cc",
+ "resolver/struct_layout_test.cc",
+ "resolver/struct_pipeline_stage_use_test.cc",
+ "resolver/struct_storage_class_use_test.cc",
+ "resolver/type_constructor_validation_test.cc",
+ "resolver/type_validation_test.cc",
+ "resolver/uniformity_test.cc",
+ "resolver/validation_test.cc",
+ "resolver/validator_is_storeable_test.cc",
+ "resolver/variable_test.cc",
+ "resolver/variable_validation_test.cc",
+ ]
+ deps = [ ":tint_unittests_ast_src" ]
+ }
+
+ tint_unittests_source_set("tint_unittests_sem_src") {
+ sources = [
+ "sem/atomic_test.cc",
+ "sem/bool_test.cc",
+ "sem/builtin_test.cc",
+ "sem/depth_multisampled_texture_test.cc",
+ "sem/depth_texture_test.cc",
+ "sem/expression_test.cc",
+ "sem/external_texture_test.cc",
+ "sem/f16_test.cc",
+ "sem/f32_test.cc",
+ "sem/i32_test.cc",
+ "sem/matrix_test.cc",
+ "sem/multisampled_texture_test.cc",
+ "sem/pointer_test.cc",
+ "sem/reference_test.cc",
+ "sem/sampled_texture_test.cc",
+ "sem/sampler_test.cc",
+ "sem/sem_array_test.cc",
+ "sem/sem_struct_test.cc",
+ "sem/storage_texture_test.cc",
+ "sem/texture_test.cc",
+ "sem/type_manager_test.cc",
+ "sem/type_test.cc",
+ "sem/u32_test.cc",
+ "sem/vector_test.cc",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_text_src") {
+ sources = [ "text/unicode_test.cc" ]
+ }
+
+ tint_unittests_source_set("tint_unittests_transform_src") {
+ sources = [
+ "transform/add_empty_entry_point_test.cc",
+ "transform/add_spirv_block_attribute_test.cc",
+ "transform/array_length_from_uniform_test.cc",
+ "transform/binding_remapper_test.cc",
+ "transform/builtin_polyfill_test.cc",
+ "transform/calculate_array_length_test.cc",
+ "transform/canonicalize_entry_point_io_test.cc",
+ "transform/combine_samplers_test.cc",
+ "transform/decompose_memory_access_test.cc",
+ "transform/decompose_strided_array_test.cc",
+ "transform/decompose_strided_matrix_test.cc",
+ "transform/disable_uniformity_analysis_test.cc",
+ "transform/expand_compound_assignment_test.cc",
+ "transform/first_index_offset_test.cc",
+ "transform/fold_trivial_single_use_lets_test.cc",
+ "transform/for_loop_to_loop_test.cc",
+ "transform/localize_struct_array_assignment_test.cc",
+ "transform/loop_to_for_loop_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",
+ "transform/promote_initializers_to_let_test.cc",
+ "transform/promote_side_effects_to_decl_test.cc",
+ "transform/remove_continue_in_switch_test.cc",
+ "transform/remove_phonies_test.cc",
+ "transform/remove_unreachable_statements_test.cc",
+ "transform/renamer_test.cc",
+ "transform/robustness_test.cc",
+ "transform/simplify_pointers_test.cc",
+ "transform/single_entry_point_test.cc",
+ "transform/spirv_atomic_test.cc",
+ "transform/test_helper.h",
+ "transform/transform_test.cc",
+ "transform/unshadow_test.cc",
+ "transform/unwind_discard_functions_test.cc",
+ "transform/utils/get_insertion_point_test.cc",
+ "transform/utils/hoist_to_decl_before_test.cc",
+ "transform/var_for_dynamic_index_test.cc",
+ "transform/vectorize_scalar_matrix_constructors_test.cc",
+ "transform/vertex_pulling_test.cc",
+ "transform/while_to_loop_test.cc",
+ "transform/zero_init_workgroup_memory_test.cc",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_utils_src") {
+ sources = [
+ "utils/bitcast_test.cc",
+ "utils/crc32_test.cc",
+ "utils/defer_test.cc",
+ "utils/enum_set_test.cc",
+ "utils/hash_test.cc",
+ "utils/io/command_test.cc",
+ "utils/io/tmpfile_test.cc",
+ "utils/map_test.cc",
+ "utils/math_test.cc",
+ "utils/result_test.cc",
+ "utils/reverse_test.cc",
+ "utils/scoped_assignment_test.cc",
+ "utils/string_test.cc",
+ "utils/transform_test.cc",
+ "utils/unique_allocator_test.cc",
+ "utils/unique_vector_test.cc",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_writer_src") {
+ sources = [
+ "writer/append_vector_test.cc",
+ "writer/flatten_bindings_test.cc",
+ "writer/float_to_string_test.cc",
+ "writer/generate_external_texture_bindings_test.cc",
+ "writer/text_generator_test.cc",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_spv_reader_src") {
+ sources = [
+ "reader/spirv/enum_converter_test.cc",
+ "reader/spirv/fail_stream_test.cc",
+ "reader/spirv/function_arithmetic_test.cc",
+ "reader/spirv/function_bit_test.cc",
+ "reader/spirv/function_call_test.cc",
+ "reader/spirv/function_cfg_test.cc",
+ "reader/spirv/function_composite_test.cc",
+ "reader/spirv/function_conversion_test.cc",
+ "reader/spirv/function_decl_test.cc",
+ "reader/spirv/function_glsl_std_450_test.cc",
+ "reader/spirv/function_logical_test.cc",
+ "reader/spirv/function_memory_test.cc",
+ "reader/spirv/function_misc_test.cc",
+ "reader/spirv/function_var_test.cc",
+ "reader/spirv/namer_test.cc",
+ "reader/spirv/parser_impl_barrier_test.cc",
+ "reader/spirv/parser_impl_convert_member_decoration_test.cc",
+ "reader/spirv/parser_impl_convert_type_test.cc",
+ "reader/spirv/parser_impl_function_decl_test.cc",
+ "reader/spirv/parser_impl_get_decorations_test.cc",
+ "reader/spirv/parser_impl_handle_test.cc",
+ "reader/spirv/parser_impl_import_test.cc",
+ "reader/spirv/parser_impl_module_var_test.cc",
+ "reader/spirv/parser_impl_named_types_test.cc",
+ "reader/spirv/parser_impl_test.cc",
+ "reader/spirv/parser_impl_test_helper.cc",
+ "reader/spirv/parser_impl_test_helper.h",
+ "reader/spirv/parser_impl_user_name_test.cc",
+ "reader/spirv/parser_test.cc",
+ "reader/spirv/parser_type_test.cc",
+ "reader/spirv/spirv_tools_helpers_test.cc",
+ "reader/spirv/spirv_tools_helpers_test.h",
+ "reader/spirv/usage_test.cc",
+ ]
+
+ deps = [ ":libtint_spv_reader_src" ]
+ }
+
+ tint_unittests_source_set("tint_unittests_spv_writer_src") {
+ sources = [
+ "writer/spirv/binary_writer_test.cc",
+ "writer/spirv/builder_accessor_expression_test.cc",
+ "writer/spirv/builder_assign_test.cc",
+ "writer/spirv/builder_binary_expression_test.cc",
+ "writer/spirv/builder_bitcast_expression_test.cc",
+ "writer/spirv/builder_block_test.cc",
+ "writer/spirv/builder_builtin_test.cc",
+ "writer/spirv/builder_builtin_texture_test.cc",
+ "writer/spirv/builder_call_test.cc",
+ "writer/spirv/builder_constructor_expression_test.cc",
+ "writer/spirv/builder_discard_test.cc",
+ "writer/spirv/builder_entry_point_test.cc",
+ "writer/spirv/builder_format_conversion_test.cc",
+ "writer/spirv/builder_function_attribute_test.cc",
+ "writer/spirv/builder_function_test.cc",
+ "writer/spirv/builder_function_variable_test.cc",
+ "writer/spirv/builder_global_variable_test.cc",
+ "writer/spirv/builder_ident_expression_test.cc",
+ "writer/spirv/builder_if_test.cc",
+ "writer/spirv/builder_literal_test.cc",
+ "writer/spirv/builder_loop_test.cc",
+ "writer/spirv/builder_return_test.cc",
+ "writer/spirv/builder_switch_test.cc",
+ "writer/spirv/builder_test.cc",
+ "writer/spirv/builder_type_test.cc",
+ "writer/spirv/builder_unary_op_expression_test.cc",
+ "writer/spirv/instruction_test.cc",
+ "writer/spirv/operand_test.cc",
+ "writer/spirv/scalar_constant_test.cc",
+ "writer/spirv/spv_dump.cc",
+ "writer/spirv/spv_dump.h",
+ "writer/spirv/test_helper.h",
+ ]
+
+ deps = [
+ ":libtint_spv_writer_src",
+ ":tint_unittests_ast_src",
+ "${tint_spirv_tools_dir}/:spvtools",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_wgsl_reader_src") {
+ sources = [
+ "reader/wgsl/lexer_test.cc",
+ "reader/wgsl/parser_impl_additive_expression_test.cc",
+ "reader/wgsl/parser_impl_and_expression_test.cc",
+ "reader/wgsl/parser_impl_argument_expression_list_test.cc",
+ "reader/wgsl/parser_impl_assignment_stmt_test.cc",
+ "reader/wgsl/parser_impl_body_stmt_test.cc",
+ "reader/wgsl/parser_impl_break_stmt_test.cc",
+ "reader/wgsl/parser_impl_bug_cases_test.cc",
+ "reader/wgsl/parser_impl_call_stmt_test.cc",
+ "reader/wgsl/parser_impl_case_body_test.cc",
+ "reader/wgsl/parser_impl_const_literal_test.cc",
+ "reader/wgsl/parser_impl_continue_stmt_test.cc",
+ "reader/wgsl/parser_impl_continuing_stmt_test.cc",
+ "reader/wgsl/parser_impl_depth_texture_test.cc",
+ "reader/wgsl/parser_impl_enable_directive_test.cc",
+ "reader/wgsl/parser_impl_equality_expression_test.cc",
+ "reader/wgsl/parser_impl_error_msg_test.cc",
+ "reader/wgsl/parser_impl_error_resync_test.cc",
+ "reader/wgsl/parser_impl_exclusive_or_expression_test.cc",
+ "reader/wgsl/parser_impl_external_texture_test.cc",
+ "reader/wgsl/parser_impl_for_stmt_test.cc",
+ "reader/wgsl/parser_impl_function_attribute_list_test.cc",
+ "reader/wgsl/parser_impl_function_attribute_test.cc",
+ "reader/wgsl/parser_impl_function_decl_test.cc",
+ "reader/wgsl/parser_impl_function_header_test.cc",
+ "reader/wgsl/parser_impl_global_constant_decl_test.cc",
+ "reader/wgsl/parser_impl_global_decl_test.cc",
+ "reader/wgsl/parser_impl_global_variable_decl_test.cc",
+ "reader/wgsl/parser_impl_if_stmt_test.cc",
+ "reader/wgsl/parser_impl_inclusive_or_expression_test.cc",
+ "reader/wgsl/parser_impl_increment_decrement_stmt_test.cc",
+ "reader/wgsl/parser_impl_logical_and_expression_test.cc",
+ "reader/wgsl/parser_impl_logical_or_expression_test.cc",
+ "reader/wgsl/parser_impl_loop_stmt_test.cc",
+ "reader/wgsl/parser_impl_multiplicative_expression_test.cc",
+ "reader/wgsl/parser_impl_param_list_test.cc",
+ "reader/wgsl/parser_impl_paren_rhs_stmt_test.cc",
+ "reader/wgsl/parser_impl_pipeline_stage_test.cc",
+ "reader/wgsl/parser_impl_primary_expression_test.cc",
+ "reader/wgsl/parser_impl_relational_expression_test.cc",
+ "reader/wgsl/parser_impl_reserved_keyword_test.cc",
+ "reader/wgsl/parser_impl_sampled_texture_test.cc",
+ "reader/wgsl/parser_impl_sampler_test.cc",
+ "reader/wgsl/parser_impl_shift_expression_test.cc",
+ "reader/wgsl/parser_impl_singular_expression_test.cc",
+ "reader/wgsl/parser_impl_statement_test.cc",
+ "reader/wgsl/parser_impl_statements_test.cc",
+ "reader/wgsl/parser_impl_storage_class_test.cc",
+ "reader/wgsl/parser_impl_storage_texture_test.cc",
+ "reader/wgsl/parser_impl_struct_attribute_decl_test.cc",
+ "reader/wgsl/parser_impl_struct_body_decl_test.cc",
+ "reader/wgsl/parser_impl_struct_decl_test.cc",
+ "reader/wgsl/parser_impl_struct_member_attribute_decl_test.cc",
+ "reader/wgsl/parser_impl_struct_member_attribute_test.cc",
+ "reader/wgsl/parser_impl_struct_member_test.cc",
+ "reader/wgsl/parser_impl_switch_body_test.cc",
+ "reader/wgsl/parser_impl_switch_stmt_test.cc",
+ "reader/wgsl/parser_impl_test.cc",
+ "reader/wgsl/parser_impl_test_helper.cc",
+ "reader/wgsl/parser_impl_test_helper.h",
+ "reader/wgsl/parser_impl_texel_format_test.cc",
+ "reader/wgsl/parser_impl_texture_sampler_test.cc",
+ "reader/wgsl/parser_impl_type_alias_test.cc",
+ "reader/wgsl/parser_impl_type_decl_test.cc",
+ "reader/wgsl/parser_impl_unary_expression_test.cc",
+ "reader/wgsl/parser_impl_variable_attribute_list_test.cc",
+ "reader/wgsl/parser_impl_variable_attribute_test.cc",
+ "reader/wgsl/parser_impl_variable_decl_test.cc",
+ "reader/wgsl/parser_impl_variable_ident_decl_test.cc",
+ "reader/wgsl/parser_impl_variable_qualifier_test.cc",
+ "reader/wgsl/parser_impl_variable_stmt_test.cc",
+ "reader/wgsl/parser_impl_while_stmt_test.cc",
+ "reader/wgsl/parser_test.cc",
+ "reader/wgsl/token_test.cc",
+ ]
+
+ deps = [ ":libtint_wgsl_reader_src" ]
+ }
+
+ tint_unittests_source_set("tint_unittests_wgsl_writer_src") {
+ sources = [
+ "writer/wgsl/generator_impl_alias_type_test.cc",
+ "writer/wgsl/generator_impl_array_accessor_test.cc",
+ "writer/wgsl/generator_impl_assign_test.cc",
+ "writer/wgsl/generator_impl_binary_test.cc",
+ "writer/wgsl/generator_impl_bitcast_test.cc",
+ "writer/wgsl/generator_impl_block_test.cc",
+ "writer/wgsl/generator_impl_break_test.cc",
+ "writer/wgsl/generator_impl_call_test.cc",
+ "writer/wgsl/generator_impl_case_test.cc",
+ "writer/wgsl/generator_impl_cast_test.cc",
+ "writer/wgsl/generator_impl_constructor_test.cc",
+ "writer/wgsl/generator_impl_continue_test.cc",
+ "writer/wgsl/generator_impl_discard_test.cc",
+ "writer/wgsl/generator_impl_enable_test.cc",
+ "writer/wgsl/generator_impl_fallthrough_test.cc",
+ "writer/wgsl/generator_impl_function_test.cc",
+ "writer/wgsl/generator_impl_global_decl_test.cc",
+ "writer/wgsl/generator_impl_identifier_test.cc",
+ "writer/wgsl/generator_impl_if_test.cc",
+ "writer/wgsl/generator_impl_literal_test.cc",
+ "writer/wgsl/generator_impl_loop_test.cc",
+ "writer/wgsl/generator_impl_member_accessor_test.cc",
+ "writer/wgsl/generator_impl_return_test.cc",
+ "writer/wgsl/generator_impl_switch_test.cc",
+ "writer/wgsl/generator_impl_test.cc",
+ "writer/wgsl/generator_impl_type_test.cc",
+ "writer/wgsl/generator_impl_unary_op_test.cc",
+ "writer/wgsl/generator_impl_variable_decl_statement_test.cc",
+ "writer/wgsl/generator_impl_variable_test.cc",
+ "writer/wgsl/test_helper.h",
+ ]
+
+ deps = [
+ ":libtint_wgsl_writer_src",
+ ":tint_unittests_ast_src",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_msl_writer_src") {
+ sources = [
+ "writer/msl/generator_impl_array_accessor_test.cc",
+ "writer/msl/generator_impl_assign_test.cc",
+ "writer/msl/generator_impl_binary_test.cc",
+ "writer/msl/generator_impl_bitcast_test.cc",
+ "writer/msl/generator_impl_block_test.cc",
+ "writer/msl/generator_impl_break_test.cc",
+ "writer/msl/generator_impl_builtin_test.cc",
+ "writer/msl/generator_impl_builtin_texture_test.cc",
+ "writer/msl/generator_impl_call_test.cc",
+ "writer/msl/generator_impl_case_test.cc",
+ "writer/msl/generator_impl_cast_test.cc",
+ "writer/msl/generator_impl_constructor_test.cc",
+ "writer/msl/generator_impl_continue_test.cc",
+ "writer/msl/generator_impl_discard_test.cc",
+ "writer/msl/generator_impl_function_test.cc",
+ "writer/msl/generator_impl_identifier_test.cc",
+ "writer/msl/generator_impl_if_test.cc",
+ "writer/msl/generator_impl_import_test.cc",
+ "writer/msl/generator_impl_loop_test.cc",
+ "writer/msl/generator_impl_member_accessor_test.cc",
+ "writer/msl/generator_impl_module_constant_test.cc",
+ "writer/msl/generator_impl_return_test.cc",
+ "writer/msl/generator_impl_sanitizer_test.cc",
+ "writer/msl/generator_impl_switch_test.cc",
+ "writer/msl/generator_impl_test.cc",
+ "writer/msl/generator_impl_type_test.cc",
+ "writer/msl/generator_impl_unary_op_test.cc",
+ "writer/msl/generator_impl_variable_decl_statement_test.cc",
+ "writer/msl/test_helper.h",
+ ]
+
+ deps = [
+ ":libtint_msl_writer_src",
+ ":tint_unittests_ast_src",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_hlsl_writer_src") {
+ sources = [
+ "writer/hlsl/generator_impl_array_accessor_test.cc",
+ "writer/hlsl/generator_impl_assign_test.cc",
+ "writer/hlsl/generator_impl_binary_test.cc",
+ "writer/hlsl/generator_impl_bitcast_test.cc",
+ "writer/hlsl/generator_impl_block_test.cc",
+ "writer/hlsl/generator_impl_break_test.cc",
+ "writer/hlsl/generator_impl_builtin_test.cc",
+ "writer/hlsl/generator_impl_builtin_texture_test.cc",
+ "writer/hlsl/generator_impl_call_test.cc",
+ "writer/hlsl/generator_impl_case_test.cc",
+ "writer/hlsl/generator_impl_cast_test.cc",
+ "writer/hlsl/generator_impl_constructor_test.cc",
+ "writer/hlsl/generator_impl_continue_test.cc",
+ "writer/hlsl/generator_impl_discard_test.cc",
+ "writer/hlsl/generator_impl_function_test.cc",
+ "writer/hlsl/generator_impl_identifier_test.cc",
+ "writer/hlsl/generator_impl_if_test.cc",
+ "writer/hlsl/generator_impl_import_test.cc",
+ "writer/hlsl/generator_impl_loop_test.cc",
+ "writer/hlsl/generator_impl_member_accessor_test.cc",
+ "writer/hlsl/generator_impl_module_constant_test.cc",
+ "writer/hlsl/generator_impl_return_test.cc",
+ "writer/hlsl/generator_impl_sanitizer_test.cc",
+ "writer/hlsl/generator_impl_switch_test.cc",
+ "writer/hlsl/generator_impl_test.cc",
+ "writer/hlsl/generator_impl_type_test.cc",
+ "writer/hlsl/generator_impl_unary_op_test.cc",
+ "writer/hlsl/generator_impl_variable_decl_statement_test.cc",
+ "writer/hlsl/generator_impl_workgroup_var_test.cc",
+ "writer/hlsl/test_helper.h",
+ ]
+
+ deps = [
+ ":libtint_hlsl_writer_src",
+ ":tint_unittests_ast_src",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_glsl_writer_src") {
+ sources = [
+ "writer/glsl/generator_impl_array_accessor_test.cc",
+ "writer/glsl/generator_impl_assign_test.cc",
+ "writer/glsl/generator_impl_binary_test.cc",
+ "writer/glsl/generator_impl_bitcast_test.cc",
+ "writer/glsl/generator_impl_block_test.cc",
+ "writer/glsl/generator_impl_break_test.cc",
+ "writer/glsl/generator_impl_builtin_test.cc",
+ "writer/glsl/generator_impl_builtin_texture_test.cc",
+ "writer/glsl/generator_impl_call_test.cc",
+ "writer/glsl/generator_impl_case_test.cc",
+ "writer/glsl/generator_impl_cast_test.cc",
+ "writer/glsl/generator_impl_constructor_test.cc",
+ "writer/glsl/generator_impl_continue_test.cc",
+ "writer/glsl/generator_impl_discard_test.cc",
+ "writer/glsl/generator_impl_function_test.cc",
+ "writer/glsl/generator_impl_identifier_test.cc",
+ "writer/glsl/generator_impl_if_test.cc",
+ "writer/glsl/generator_impl_import_test.cc",
+ "writer/glsl/generator_impl_loop_test.cc",
+ "writer/glsl/generator_impl_member_accessor_test.cc",
+ "writer/glsl/generator_impl_module_constant_test.cc",
+ "writer/glsl/generator_impl_return_test.cc",
+ "writer/glsl/generator_impl_sanitizer_test.cc",
+ "writer/glsl/generator_impl_storage_buffer_test.cc",
+ "writer/glsl/generator_impl_switch_test.cc",
+ "writer/glsl/generator_impl_test.cc",
+ "writer/glsl/generator_impl_type_test.cc",
+ "writer/glsl/generator_impl_unary_op_test.cc",
+ "writer/glsl/generator_impl_uniform_buffer_test.cc",
+ "writer/glsl/generator_impl_variable_decl_statement_test.cc",
+ "writer/glsl/generator_impl_workgroup_var_test.cc",
+ "writer/glsl/test_helper.h",
+ ]
+
+ deps = [
+ ":libtint_glsl_writer_src",
+ ":tint_unittests_ast_src",
+ ":tint_unittests_transform_src",
+ ]
+ }
+
+ tint_unittests_source_set("tint_unittests_core_src") {
+ sources = [
+ "castable_test.cc",
+ "clone_context_test.cc",
+ "debug_test.cc",
+ "demangler_test.cc",
+ "number_test.cc",
+ "program_builder_test.cc",
+ "program_test.cc",
+ "scope_stack_test.cc",
+ "source_test.cc",
+ "symbol_table_test.cc",
+ "symbol_test.cc",
+ "traits_test.cc",
+ "utils/block_allocator_test.cc",
+ ]
+
+ deps = [ ":tint_unittests_ast_src" ]
+ }
+
+ if (build_with_chromium) {
+ tint_unittests_source_set("tint_unittests_fuzzer_src") {
+ sources = [ "fuzzers/random_generator_test.cc" ]
+
+ deps = [
+ ":tint_unittests_core_src",
+ "fuzzers:tint_fuzzer_common_src",
+ ]
+ }
+ }
+
+ source_set("tint_unittests_src") {
+ testonly = true
+
+ deps = [
+ ":libtint_wgsl_reader_src",
+ ":libtint_wgsl_writer_src",
+ ":tint_unittests_ast_src",
+ ":tint_unittests_core_src",
+ ":tint_unittests_diagnostic_src",
+ ":tint_unittests_inspector_src",
+ ":tint_unittests_resolver_src",
+ ":tint_unittests_sem_src",
+ ":tint_unittests_text_src",
+ ":tint_unittests_transform_src",
+ ":tint_unittests_utils_src",
+ ":tint_unittests_writer_src",
+ ]
+
+ if (tint_build_spv_reader) {
+ deps += [ ":tint_unittests_spv_reader_src" ]
+ }
+
+ if (tint_build_spv_writer) {
+ deps += [ ":tint_unittests_spv_writer_src" ]
+ }
+
+ if (tint_build_wgsl_reader) {
+ deps += [ ":tint_unittests_wgsl_reader_src" ]
+ }
+
+ if (tint_build_wgsl_writer) {
+ deps += [ ":tint_unittests_wgsl_writer_src" ]
+ }
+
+ if (tint_build_msl_writer) {
+ deps += [ ":tint_unittests_msl_writer_src" ]
+ }
+
+ if (tint_build_hlsl_writer) {
+ deps += [ ":tint_unittests_hlsl_writer_src" ]
+ }
+
+ if (tint_build_glsl_writer) {
+ deps += [ ":tint_unittests_glsl_writer_src" ]
+ }
+
+ if (build_with_chromium) {
+ deps += [ ":tint_unittests_fuzzer_src" ]
+ }
+
configs += [ ":tint_unittests_config" ]
+
+ if (build_with_chromium) {
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [ "//build/config/compiler:no_chromium_code" ]
+ }
+ }
+
+ test("tint_unittests") {
+ deps = [
+ ":gmock_and_gtest",
+ ":tint_unittests_src",
+ "${tint_spirv_tools_dir}/:spvtools",
+ "${tint_spirv_tools_dir}/:spvtools_opt",
+ "${tint_spirv_tools_dir}/:spvtools_val",
+ ]
+
+ deps += [ ":tint_unittests_main" ]
+
+ configs += [ ":tint_unittests_config" ]
+
if (build_with_chromium) {
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
}
testonly = true
-
- if (!defined(invoker.deps)) {
- deps = []
- }
- deps += [
- ":gmock_and_gtest",
- ":libtint",
- ":tint_utils_io",
- ]
}
}
-
-tint_unittests_source_set("tint_unittests_ast_src") {
- sources = [
- "ast/alias_test.cc",
- "ast/array_test.cc",
- "ast/assignment_statement_test.cc",
- "ast/atomic_test.cc",
- "ast/binary_expression_test.cc",
- "ast/binding_attribute_test.cc",
- "ast/bitcast_expression_test.cc",
- "ast/block_statement_test.cc",
- "ast/bool_literal_expression_test.cc",
- "ast/bool_test.cc",
- "ast/break_statement_test.cc",
- "ast/builtin_attribute_test.cc",
- "ast/builtin_texture_helper_test.cc",
- "ast/builtin_texture_helper_test.h",
- "ast/call_expression_test.cc",
- "ast/call_statement_test.cc",
- "ast/case_statement_test.cc",
- "ast/compound_assignment_statement_test.cc",
- "ast/continue_statement_test.cc",
- "ast/depth_multisampled_texture_test.cc",
- "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",
- "ast/fallthrough_statement_test.cc",
- "ast/float_literal_expression_test.cc",
- "ast/for_loop_statement_test.cc",
- "ast/function_test.cc",
- "ast/group_attribute_test.cc",
- "ast/i32_test.cc",
- "ast/id_attribute_test.cc",
- "ast/identifier_expression_test.cc",
- "ast/if_statement_test.cc",
- "ast/increment_decrement_statement_test.cc",
- "ast/index_accessor_expression_test.cc",
- "ast/int_literal_expression_test.cc",
- "ast/interpolate_attribute_test.cc",
- "ast/invariant_attribute_test.cc",
- "ast/location_attribute_test.cc",
- "ast/loop_statement_test.cc",
- "ast/matrix_test.cc",
- "ast/member_accessor_expression_test.cc",
- "ast/module_clone_test.cc",
- "ast/module_test.cc",
- "ast/multisampled_texture_test.cc",
- "ast/phony_expression_test.cc",
- "ast/pointer_test.cc",
- "ast/return_statement_test.cc",
- "ast/sampled_texture_test.cc",
- "ast/sampler_test.cc",
- "ast/stage_attribute_test.cc",
- "ast/storage_texture_test.cc",
- "ast/stride_attribute_test.cc",
- "ast/struct_member_align_attribute_test.cc",
- "ast/struct_member_offset_attribute_test.cc",
- "ast/struct_member_size_attribute_test.cc",
- "ast/struct_member_test.cc",
- "ast/struct_test.cc",
- "ast/switch_statement_test.cc",
- "ast/test_helper.h",
- "ast/texture_test.cc",
- "ast/traverse_expressions_test.cc",
- "ast/u32_test.cc",
- "ast/unary_op_expression_test.cc",
- "ast/variable_decl_statement_test.cc",
- "ast/variable_test.cc",
- "ast/vector_test.cc",
- "ast/while_statement_test.cc",
- "ast/workgroup_attribute_test.cc",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_diagnostic_src") {
- sources = [
- "diagnostic/diagnostic_test.cc",
- "diagnostic/formatter_test.cc",
- "diagnostic/printer_test.cc",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_inspector_src") {
- sources = [
- "inspector/inspector_test.cc",
- "inspector/test_inspector_builder.cc",
- "inspector/test_inspector_builder.h",
- "inspector/test_inspector_runner.cc",
- "inspector/test_inspector_runner.h",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_resolver_src") {
- sources = [
- "resolver/array_accessor_test.cc",
- "resolver/assignment_validation_test.cc",
- "resolver/atomics_test.cc",
- "resolver/atomics_validation_test.cc",
- "resolver/attribute_validation_test.cc",
- "resolver/bitcast_validation_test.cc",
- "resolver/builtin_test.cc",
- "resolver/builtin_validation_test.cc",
- "resolver/builtins_validation_test.cc",
- "resolver/call_test.cc",
- "resolver/call_validation_test.cc",
- "resolver/compound_assignment_validation_test.cc",
- "resolver/compound_statement_test.cc",
- "resolver/control_block_validation_test.cc",
- "resolver/dependency_graph_test.cc",
- "resolver/entry_point_validation_test.cc",
- "resolver/function_validation_test.cc",
- "resolver/host_shareable_validation_test.cc",
- "resolver/increment_decrement_validation_test.cc",
- "resolver/intrinsic_table_test.cc",
- "resolver/is_host_shareable_test.cc",
- "resolver/is_storeable_test.cc",
- "resolver/materialize_test.cc",
- "resolver/pipeline_overridable_constant_test.cc",
- "resolver/ptr_ref_test.cc",
- "resolver/ptr_ref_validation_test.cc",
- "resolver/resolver_behavior_test.cc",
- "resolver/resolver_constants_test.cc",
- "resolver/resolver_test.cc",
- "resolver/resolver_test_helper.cc",
- "resolver/resolver_test_helper.h",
- "resolver/side_effects_test.cc",
- "resolver/source_variable_test.cc",
- "resolver/storage_class_layout_validation_test.cc",
- "resolver/storage_class_validation_test.cc",
- "resolver/struct_layout_test.cc",
- "resolver/struct_pipeline_stage_use_test.cc",
- "resolver/struct_storage_class_use_test.cc",
- "resolver/type_constructor_validation_test.cc",
- "resolver/type_validation_test.cc",
- "resolver/uniformity_test.cc",
- "resolver/validation_test.cc",
- "resolver/validator_is_storeable_test.cc",
- "resolver/var_let_test.cc",
- "resolver/var_let_validation_test.cc",
- ]
- deps = [ ":tint_unittests_ast_src" ]
-}
-
-tint_unittests_source_set("tint_unittests_sem_src") {
- sources = [
- "sem/atomic_test.cc",
- "sem/bool_test.cc",
- "sem/builtin_test.cc",
- "sem/constant_test.cc",
- "sem/depth_multisampled_texture_test.cc",
- "sem/depth_texture_test.cc",
- "sem/expression_test.cc",
- "sem/external_texture_test.cc",
- "sem/f16_test.cc",
- "sem/f32_test.cc",
- "sem/i32_test.cc",
- "sem/matrix_test.cc",
- "sem/multisampled_texture_test.cc",
- "sem/pointer_test.cc",
- "sem/reference_test.cc",
- "sem/sampled_texture_test.cc",
- "sem/sampler_test.cc",
- "sem/sem_array_test.cc",
- "sem/sem_struct_test.cc",
- "sem/storage_texture_test.cc",
- "sem/texture_test.cc",
- "sem/type_manager_test.cc",
- "sem/type_test.cc",
- "sem/u32_test.cc",
- "sem/vector_test.cc",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_text_src") {
- sources = [ "text/unicode_test.cc" ]
-}
-
-tint_unittests_source_set("tint_unittests_transform_src") {
- sources = [
- "transform/add_empty_entry_point_test.cc",
- "transform/add_spirv_block_attribute_test.cc",
- "transform/array_length_from_uniform_test.cc",
- "transform/binding_remapper_test.cc",
- "transform/builtin_polyfill_test.cc",
- "transform/calculate_array_length_test.cc",
- "transform/canonicalize_entry_point_io_test.cc",
- "transform/combine_samplers_test.cc",
- "transform/decompose_memory_access_test.cc",
- "transform/decompose_strided_array_test.cc",
- "transform/decompose_strided_matrix_test.cc",
- "transform/disable_uniformity_analysis_test.cc",
- "transform/expand_compound_assignment_test.cc",
- "transform/first_index_offset_test.cc",
- "transform/fold_trivial_single_use_lets_test.cc",
- "transform/for_loop_to_loop_test.cc",
- "transform/localize_struct_array_assignment_test.cc",
- "transform/loop_to_for_loop_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",
- "transform/promote_initializers_to_const_var_test.cc",
- "transform/promote_side_effects_to_decl_test.cc",
- "transform/remove_continue_in_switch_test.cc",
- "transform/remove_phonies_test.cc",
- "transform/remove_unreachable_statements_test.cc",
- "transform/renamer_test.cc",
- "transform/robustness_test.cc",
- "transform/simplify_pointers_test.cc",
- "transform/single_entry_point_test.cc",
- "transform/test_helper.h",
- "transform/transform_test.cc",
- "transform/unshadow_test.cc",
- "transform/unwind_discard_functions_test.cc",
- "transform/utils/get_insertion_point_test.cc",
- "transform/utils/hoist_to_decl_before_test.cc",
- "transform/var_for_dynamic_index_test.cc",
- "transform/vectorize_scalar_matrix_constructors_test.cc",
- "transform/vertex_pulling_test.cc",
- "transform/while_to_loop_test.cc",
- "transform/wrap_arrays_in_structs_test.cc",
- "transform/zero_init_workgroup_memory_test.cc",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_utils_src") {
- sources = [
- "utils/bitcast_test.cc",
- "utils/crc32_test.cc",
- "utils/defer_test.cc",
- "utils/enum_set_test.cc",
- "utils/hash_test.cc",
- "utils/io/command_test.cc",
- "utils/io/tmpfile_test.cc",
- "utils/map_test.cc",
- "utils/math_test.cc",
- "utils/result_test.cc",
- "utils/reverse_test.cc",
- "utils/scoped_assignment_test.cc",
- "utils/string_test.cc",
- "utils/transform_test.cc",
- "utils/unique_allocator_test.cc",
- "utils/unique_vector_test.cc",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_writer_src") {
- sources = [
- "writer/append_vector_test.cc",
- "writer/flatten_bindings_test.cc",
- "writer/float_to_string_test.cc",
- "writer/generate_external_texture_bindings_test.cc",
- "writer/text_generator_test.cc",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_spv_reader_src") {
- sources = [
- "reader/spirv/enum_converter_test.cc",
- "reader/spirv/fail_stream_test.cc",
- "reader/spirv/function_arithmetic_test.cc",
- "reader/spirv/function_bit_test.cc",
- "reader/spirv/function_call_test.cc",
- "reader/spirv/function_cfg_test.cc",
- "reader/spirv/function_composite_test.cc",
- "reader/spirv/function_conversion_test.cc",
- "reader/spirv/function_decl_test.cc",
- "reader/spirv/function_glsl_std_450_test.cc",
- "reader/spirv/function_logical_test.cc",
- "reader/spirv/function_memory_test.cc",
- "reader/spirv/function_misc_test.cc",
- "reader/spirv/function_var_test.cc",
- "reader/spirv/namer_test.cc",
- "reader/spirv/parser_impl_barrier_test.cc",
- "reader/spirv/parser_impl_convert_member_decoration_test.cc",
- "reader/spirv/parser_impl_convert_type_test.cc",
- "reader/spirv/parser_impl_function_decl_test.cc",
- "reader/spirv/parser_impl_get_decorations_test.cc",
- "reader/spirv/parser_impl_handle_test.cc",
- "reader/spirv/parser_impl_import_test.cc",
- "reader/spirv/parser_impl_module_var_test.cc",
- "reader/spirv/parser_impl_named_types_test.cc",
- "reader/spirv/parser_impl_test.cc",
- "reader/spirv/parser_impl_test_helper.cc",
- "reader/spirv/parser_impl_test_helper.h",
- "reader/spirv/parser_impl_user_name_test.cc",
- "reader/spirv/parser_test.cc",
- "reader/spirv/parser_type_test.cc",
- "reader/spirv/spirv_tools_helpers_test.cc",
- "reader/spirv/spirv_tools_helpers_test.h",
- "reader/spirv/usage_test.cc",
- ]
-
- deps = [ ":libtint_spv_reader_src" ]
-}
-
-tint_unittests_source_set("tint_unittests_spv_writer_src") {
- sources = [
- "writer/spirv/binary_writer_test.cc",
- "writer/spirv/builder_accessor_expression_test.cc",
- "writer/spirv/builder_assign_test.cc",
- "writer/spirv/builder_binary_expression_test.cc",
- "writer/spirv/builder_bitcast_expression_test.cc",
- "writer/spirv/builder_block_test.cc",
- "writer/spirv/builder_builtin_test.cc",
- "writer/spirv/builder_builtin_texture_test.cc",
- "writer/spirv/builder_call_test.cc",
- "writer/spirv/builder_constructor_expression_test.cc",
- "writer/spirv/builder_discard_test.cc",
- "writer/spirv/builder_entry_point_test.cc",
- "writer/spirv/builder_format_conversion_test.cc",
- "writer/spirv/builder_function_attribute_test.cc",
- "writer/spirv/builder_function_test.cc",
- "writer/spirv/builder_function_variable_test.cc",
- "writer/spirv/builder_global_variable_test.cc",
- "writer/spirv/builder_ident_expression_test.cc",
- "writer/spirv/builder_if_test.cc",
- "writer/spirv/builder_literal_test.cc",
- "writer/spirv/builder_loop_test.cc",
- "writer/spirv/builder_return_test.cc",
- "writer/spirv/builder_switch_test.cc",
- "writer/spirv/builder_test.cc",
- "writer/spirv/builder_type_test.cc",
- "writer/spirv/builder_unary_op_expression_test.cc",
- "writer/spirv/instruction_test.cc",
- "writer/spirv/operand_test.cc",
- "writer/spirv/scalar_constant_test.cc",
- "writer/spirv/spv_dump.cc",
- "writer/spirv/spv_dump.h",
- "writer/spirv/test_helper.h",
- ]
-
- deps = [
- ":libtint_spv_writer_src",
- ":tint_unittests_ast_src",
- "${tint_spirv_tools_dir}/:spvtools",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_wgsl_reader_src") {
- sources = [
- "reader/wgsl/lexer_test.cc",
- "reader/wgsl/parser_impl_additive_expression_test.cc",
- "reader/wgsl/parser_impl_and_expression_test.cc",
- "reader/wgsl/parser_impl_argument_expression_list_test.cc",
- "reader/wgsl/parser_impl_assignment_stmt_test.cc",
- "reader/wgsl/parser_impl_body_stmt_test.cc",
- "reader/wgsl/parser_impl_break_stmt_test.cc",
- "reader/wgsl/parser_impl_bug_cases_test.cc",
- "reader/wgsl/parser_impl_call_stmt_test.cc",
- "reader/wgsl/parser_impl_case_body_test.cc",
- "reader/wgsl/parser_impl_const_expr_test.cc",
- "reader/wgsl/parser_impl_const_literal_test.cc",
- "reader/wgsl/parser_impl_continue_stmt_test.cc",
- "reader/wgsl/parser_impl_continuing_stmt_test.cc",
- "reader/wgsl/parser_impl_depth_texture_test.cc",
- "reader/wgsl/parser_impl_enable_directive_test.cc",
- "reader/wgsl/parser_impl_equality_expression_test.cc",
- "reader/wgsl/parser_impl_error_msg_test.cc",
- "reader/wgsl/parser_impl_error_resync_test.cc",
- "reader/wgsl/parser_impl_exclusive_or_expression_test.cc",
- "reader/wgsl/parser_impl_external_texture_test.cc",
- "reader/wgsl/parser_impl_for_stmt_test.cc",
- "reader/wgsl/parser_impl_function_attribute_list_test.cc",
- "reader/wgsl/parser_impl_function_attribute_test.cc",
- "reader/wgsl/parser_impl_function_decl_test.cc",
- "reader/wgsl/parser_impl_function_header_test.cc",
- "reader/wgsl/parser_impl_global_constant_decl_test.cc",
- "reader/wgsl/parser_impl_global_decl_test.cc",
- "reader/wgsl/parser_impl_global_variable_decl_test.cc",
- "reader/wgsl/parser_impl_if_stmt_test.cc",
- "reader/wgsl/parser_impl_inclusive_or_expression_test.cc",
- "reader/wgsl/parser_impl_increment_decrement_stmt_test.cc",
- "reader/wgsl/parser_impl_logical_and_expression_test.cc",
- "reader/wgsl/parser_impl_logical_or_expression_test.cc",
- "reader/wgsl/parser_impl_loop_stmt_test.cc",
- "reader/wgsl/parser_impl_multiplicative_expression_test.cc",
- "reader/wgsl/parser_impl_param_list_test.cc",
- "reader/wgsl/parser_impl_paren_rhs_stmt_test.cc",
- "reader/wgsl/parser_impl_pipeline_stage_test.cc",
- "reader/wgsl/parser_impl_primary_expression_test.cc",
- "reader/wgsl/parser_impl_relational_expression_test.cc",
- "reader/wgsl/parser_impl_reserved_keyword_test.cc",
- "reader/wgsl/parser_impl_sampled_texture_test.cc",
- "reader/wgsl/parser_impl_sampler_test.cc",
- "reader/wgsl/parser_impl_shift_expression_test.cc",
- "reader/wgsl/parser_impl_singular_expression_test.cc",
- "reader/wgsl/parser_impl_statement_test.cc",
- "reader/wgsl/parser_impl_statements_test.cc",
- "reader/wgsl/parser_impl_storage_class_test.cc",
- "reader/wgsl/parser_impl_storage_texture_test.cc",
- "reader/wgsl/parser_impl_struct_attribute_decl_test.cc",
- "reader/wgsl/parser_impl_struct_body_decl_test.cc",
- "reader/wgsl/parser_impl_struct_decl_test.cc",
- "reader/wgsl/parser_impl_struct_member_attribute_decl_test.cc",
- "reader/wgsl/parser_impl_struct_member_attribute_test.cc",
- "reader/wgsl/parser_impl_struct_member_test.cc",
- "reader/wgsl/parser_impl_switch_body_test.cc",
- "reader/wgsl/parser_impl_switch_stmt_test.cc",
- "reader/wgsl/parser_impl_test.cc",
- "reader/wgsl/parser_impl_test_helper.cc",
- "reader/wgsl/parser_impl_test_helper.h",
- "reader/wgsl/parser_impl_texel_format_test.cc",
- "reader/wgsl/parser_impl_texture_sampler_test.cc",
- "reader/wgsl/parser_impl_type_alias_test.cc",
- "reader/wgsl/parser_impl_type_decl_test.cc",
- "reader/wgsl/parser_impl_unary_expression_test.cc",
- "reader/wgsl/parser_impl_variable_attribute_list_test.cc",
- "reader/wgsl/parser_impl_variable_attribute_test.cc",
- "reader/wgsl/parser_impl_variable_decl_test.cc",
- "reader/wgsl/parser_impl_variable_ident_decl_test.cc",
- "reader/wgsl/parser_impl_variable_qualifier_test.cc",
- "reader/wgsl/parser_impl_variable_stmt_test.cc",
- "reader/wgsl/parser_impl_while_stmt_test.cc",
- "reader/wgsl/parser_test.cc",
- "reader/wgsl/token_test.cc",
- ]
-
- deps = [ ":libtint_wgsl_reader_src" ]
-}
-
-tint_unittests_source_set("tint_unittests_wgsl_writer_src") {
- sources = [
- "writer/wgsl/generator_impl_alias_type_test.cc",
- "writer/wgsl/generator_impl_array_accessor_test.cc",
- "writer/wgsl/generator_impl_assign_test.cc",
- "writer/wgsl/generator_impl_binary_test.cc",
- "writer/wgsl/generator_impl_bitcast_test.cc",
- "writer/wgsl/generator_impl_block_test.cc",
- "writer/wgsl/generator_impl_break_test.cc",
- "writer/wgsl/generator_impl_call_test.cc",
- "writer/wgsl/generator_impl_case_test.cc",
- "writer/wgsl/generator_impl_cast_test.cc",
- "writer/wgsl/generator_impl_constructor_test.cc",
- "writer/wgsl/generator_impl_continue_test.cc",
- "writer/wgsl/generator_impl_discard_test.cc",
- "writer/wgsl/generator_impl_enable_test.cc",
- "writer/wgsl/generator_impl_fallthrough_test.cc",
- "writer/wgsl/generator_impl_function_test.cc",
- "writer/wgsl/generator_impl_global_decl_test.cc",
- "writer/wgsl/generator_impl_identifier_test.cc",
- "writer/wgsl/generator_impl_if_test.cc",
- "writer/wgsl/generator_impl_literal_test.cc",
- "writer/wgsl/generator_impl_loop_test.cc",
- "writer/wgsl/generator_impl_member_accessor_test.cc",
- "writer/wgsl/generator_impl_return_test.cc",
- "writer/wgsl/generator_impl_switch_test.cc",
- "writer/wgsl/generator_impl_test.cc",
- "writer/wgsl/generator_impl_type_test.cc",
- "writer/wgsl/generator_impl_unary_op_test.cc",
- "writer/wgsl/generator_impl_variable_decl_statement_test.cc",
- "writer/wgsl/generator_impl_variable_test.cc",
- "writer/wgsl/test_helper.h",
- ]
-
- deps = [
- ":libtint_wgsl_writer_src",
- ":tint_unittests_ast_src",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_msl_writer_src") {
- sources = [
- "writer/msl/generator_impl_array_accessor_test.cc",
- "writer/msl/generator_impl_assign_test.cc",
- "writer/msl/generator_impl_binary_test.cc",
- "writer/msl/generator_impl_bitcast_test.cc",
- "writer/msl/generator_impl_block_test.cc",
- "writer/msl/generator_impl_break_test.cc",
- "writer/msl/generator_impl_builtin_test.cc",
- "writer/msl/generator_impl_builtin_texture_test.cc",
- "writer/msl/generator_impl_call_test.cc",
- "writer/msl/generator_impl_case_test.cc",
- "writer/msl/generator_impl_cast_test.cc",
- "writer/msl/generator_impl_constructor_test.cc",
- "writer/msl/generator_impl_continue_test.cc",
- "writer/msl/generator_impl_discard_test.cc",
- "writer/msl/generator_impl_function_test.cc",
- "writer/msl/generator_impl_identifier_test.cc",
- "writer/msl/generator_impl_if_test.cc",
- "writer/msl/generator_impl_import_test.cc",
- "writer/msl/generator_impl_loop_test.cc",
- "writer/msl/generator_impl_member_accessor_test.cc",
- "writer/msl/generator_impl_module_constant_test.cc",
- "writer/msl/generator_impl_return_test.cc",
- "writer/msl/generator_impl_sanitizer_test.cc",
- "writer/msl/generator_impl_switch_test.cc",
- "writer/msl/generator_impl_test.cc",
- "writer/msl/generator_impl_type_test.cc",
- "writer/msl/generator_impl_unary_op_test.cc",
- "writer/msl/generator_impl_variable_decl_statement_test.cc",
- "writer/msl/test_helper.h",
- ]
-
- deps = [
- ":libtint_msl_writer_src",
- ":tint_unittests_ast_src",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_hlsl_writer_src") {
- sources = [
- "writer/hlsl/generator_impl_array_accessor_test.cc",
- "writer/hlsl/generator_impl_assign_test.cc",
- "writer/hlsl/generator_impl_binary_test.cc",
- "writer/hlsl/generator_impl_bitcast_test.cc",
- "writer/hlsl/generator_impl_block_test.cc",
- "writer/hlsl/generator_impl_break_test.cc",
- "writer/hlsl/generator_impl_builtin_test.cc",
- "writer/hlsl/generator_impl_builtin_texture_test.cc",
- "writer/hlsl/generator_impl_call_test.cc",
- "writer/hlsl/generator_impl_case_test.cc",
- "writer/hlsl/generator_impl_cast_test.cc",
- "writer/hlsl/generator_impl_constructor_test.cc",
- "writer/hlsl/generator_impl_continue_test.cc",
- "writer/hlsl/generator_impl_discard_test.cc",
- "writer/hlsl/generator_impl_function_test.cc",
- "writer/hlsl/generator_impl_identifier_test.cc",
- "writer/hlsl/generator_impl_if_test.cc",
- "writer/hlsl/generator_impl_import_test.cc",
- "writer/hlsl/generator_impl_loop_test.cc",
- "writer/hlsl/generator_impl_member_accessor_test.cc",
- "writer/hlsl/generator_impl_module_constant_test.cc",
- "writer/hlsl/generator_impl_return_test.cc",
- "writer/hlsl/generator_impl_sanitizer_test.cc",
- "writer/hlsl/generator_impl_switch_test.cc",
- "writer/hlsl/generator_impl_test.cc",
- "writer/hlsl/generator_impl_type_test.cc",
- "writer/hlsl/generator_impl_unary_op_test.cc",
- "writer/hlsl/generator_impl_variable_decl_statement_test.cc",
- "writer/hlsl/generator_impl_workgroup_var_test.cc",
- "writer/hlsl/test_helper.h",
- ]
-
- deps = [
- ":libtint_hlsl_writer_src",
- ":tint_unittests_ast_src",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_glsl_writer_src") {
- sources = [
- "writer/glsl/generator_impl_array_accessor_test.cc",
- "writer/glsl/generator_impl_assign_test.cc",
- "writer/glsl/generator_impl_binary_test.cc",
- "writer/glsl/generator_impl_bitcast_test.cc",
- "writer/glsl/generator_impl_block_test.cc",
- "writer/glsl/generator_impl_break_test.cc",
- "writer/glsl/generator_impl_builtin_test.cc",
- "writer/glsl/generator_impl_builtin_texture_test.cc",
- "writer/glsl/generator_impl_call_test.cc",
- "writer/glsl/generator_impl_case_test.cc",
- "writer/glsl/generator_impl_cast_test.cc",
- "writer/glsl/generator_impl_constructor_test.cc",
- "writer/glsl/generator_impl_continue_test.cc",
- "writer/glsl/generator_impl_discard_test.cc",
- "writer/glsl/generator_impl_function_test.cc",
- "writer/glsl/generator_impl_identifier_test.cc",
- "writer/glsl/generator_impl_if_test.cc",
- "writer/glsl/generator_impl_import_test.cc",
- "writer/glsl/generator_impl_loop_test.cc",
- "writer/glsl/generator_impl_member_accessor_test.cc",
- "writer/glsl/generator_impl_module_constant_test.cc",
- "writer/glsl/generator_impl_return_test.cc",
- "writer/glsl/generator_impl_sanitizer_test.cc",
- "writer/glsl/generator_impl_storage_buffer_test.cc",
- "writer/glsl/generator_impl_switch_test.cc",
- "writer/glsl/generator_impl_test.cc",
- "writer/glsl/generator_impl_type_test.cc",
- "writer/glsl/generator_impl_unary_op_test.cc",
- "writer/glsl/generator_impl_uniform_buffer_test.cc",
- "writer/glsl/generator_impl_variable_decl_statement_test.cc",
- "writer/glsl/generator_impl_workgroup_var_test.cc",
- "writer/glsl/test_helper.h",
- ]
-
- deps = [
- ":libtint_glsl_writer_src",
- ":tint_unittests_ast_src",
- ":tint_unittests_transform_src",
- ]
-}
-
-tint_unittests_source_set("tint_unittests_core_src") {
- sources = [
- "castable_test.cc",
- "clone_context_test.cc",
- "debug_test.cc",
- "demangler_test.cc",
- "number_test.cc",
- "program_builder_test.cc",
- "program_test.cc",
- "scope_stack_test.cc",
- "source_test.cc",
- "symbol_table_test.cc",
- "symbol_test.cc",
- "traits_test.cc",
- "utils/block_allocator_test.cc",
- ]
-
- deps = [ ":tint_unittests_ast_src" ]
-}
-
-if (build_with_chromium) {
- tint_unittests_source_set("tint_unittests_fuzzer_src") {
- sources = [ "fuzzers/random_generator_test.cc" ]
-
- deps = [
- ":tint_unittests_core_src",
- "fuzzers:tint_fuzzer_common_src",
- ]
- }
-}
-
-source_set("tint_unittests_src") {
- testonly = true
-
- deps = [
- ":libtint_wgsl_reader_src",
- ":libtint_wgsl_writer_src",
- ":tint_unittests_ast_src",
- ":tint_unittests_core_src",
- ":tint_unittests_diagnostic_src",
- ":tint_unittests_inspector_src",
- ":tint_unittests_resolver_src",
- ":tint_unittests_sem_src",
- ":tint_unittests_text_src",
- ":tint_unittests_transform_src",
- ":tint_unittests_utils_src",
- ":tint_unittests_writer_src",
- ]
-
- if (tint_build_spv_reader) {
- deps += [ ":tint_unittests_spv_reader_src" ]
- }
-
- if (tint_build_spv_writer) {
- deps += [ ":tint_unittests_spv_writer_src" ]
- }
-
- if (tint_build_wgsl_reader) {
- deps += [ ":tint_unittests_wgsl_reader_src" ]
- }
-
- if (tint_build_wgsl_writer) {
- deps += [ ":tint_unittests_wgsl_writer_src" ]
- }
-
- if (tint_build_msl_writer) {
- deps += [ ":tint_unittests_msl_writer_src" ]
- }
-
- if (tint_build_hlsl_writer) {
- deps += [ ":tint_unittests_hlsl_writer_src" ]
- }
-
- if (tint_build_glsl_writer) {
- deps += [ ":tint_unittests_glsl_writer_src" ]
- }
-
- if (build_with_chromium) {
- deps += [ ":tint_unittests_fuzzer_src" ]
- }
-
- configs += [ ":tint_unittests_config" ]
-
- if (build_with_chromium) {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- }
-}
-
-test("tint_unittests") {
- deps = [
- ":gmock_and_gtest",
- ":tint_unittests_src",
- "${tint_spirv_tools_dir}/:spvtools",
- "${tint_spirv_tools_dir}/:spvtools_opt",
- "${tint_spirv_tools_dir}/:spvtools_val",
- ]
-
- deps += [ ":tint_unittests_main" ]
-
- configs += [ ":tint_unittests_config" ]
-
- if (build_with_chromium) {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- }
-
- testonly = true
-}
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index f7fb14a..3e7154c 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -22,18 +22,6 @@
${spirv-tools_SOURCE_DIR}
${spirv-tools_BINARY_DIR}
)
-
- if (${CMAKE_CXX_COMPILER_ID} MATCHES Clang)
- # The SPIRV-Tools code is conditioned against C++ and an older version of Clang.
- # Suppress warnings triggered in our current compilation environment.
- # TODO(dneto): Fix the issues upstream.
- target_compile_options(${TARGET} PRIVATE
- -Wno-newline-eof
- -Wno-sign-conversion
- -Wno-old-style-cast
- -Wno-weak-vtables
- )
- endif()
endfunction()
## Tint diagnostic utilities. Used by libtint and tint_utils_io.
@@ -99,6 +87,8 @@
ast/case_statement.h
ast/compound_assignment_statement.cc
ast/compound_assignment_statement.h
+ ast/const.cc
+ ast/const.h
ast/continue_statement.cc
ast/continue_statement.h
ast/depth_multisampled_texture.cc
@@ -324,6 +314,8 @@
sem/i32.h
sem/if_statement.cc
sem/if_statement.h
+ sem/index_accessor_expression.cc
+ sem/index_accessor_expression.h
sem/info.cc
sem/info.h
sem/loop_statement.cc
@@ -428,8 +420,8 @@
transform/multiplanar_external_texture.h
transform/num_workgroups_from_uniform.cc
transform/num_workgroups_from_uniform.h
- transform/promote_initializers_to_const_var.cc
- transform/promote_initializers_to_const_var.h
+ transform/promote_initializers_to_let.cc
+ transform/promote_initializers_to_let.h
transform/promote_side_effects_to_decl.cc
transform/promote_side_effects_to_decl.h
transform/remove_continue_in_switch.cc
@@ -446,6 +438,8 @@
transform/simplify_pointers.h
transform/single_entry_point.cc
transform/single_entry_point.h
+ transform/spirv_atomic.cc
+ transform/spirv_atomic.h
transform/transform.cc
transform/transform.h
transform/unshadow.cc
@@ -464,8 +458,6 @@
transform/vertex_pulling.h
transform/while_to_loop.cc
transform/while_to_loop.h
- transform/wrap_arrays_in_structs.cc
- transform/wrap_arrays_in_structs.h
transform/zero_init_workgroup_memory.cc
transform/zero_init_workgroup_memory.h
utils/bitcast.h
@@ -812,13 +804,12 @@
resolver/type_validation_test.cc
resolver/validation_test.cc
resolver/validator_is_storeable_test.cc
- resolver/var_let_test.cc
- resolver/var_let_validation_test.cc
+ resolver/variable_test.cc
+ resolver/variable_validation_test.cc
scope_stack_test.cc
sem/atomic.cc
sem/bool_test.cc
sem/builtin_test.cc
- sem/constant_test.cc
sem/depth_multisampled_texture_test.cc
sem/depth_texture_test.cc
sem/expression_test.cc
@@ -940,7 +931,6 @@
reader/wgsl/parser_impl_bug_cases_test.cc
reader/wgsl/parser_impl_call_stmt_test.cc
reader/wgsl/parser_impl_case_body_test.cc
- reader/wgsl/parser_impl_const_expr_test.cc
reader/wgsl/parser_impl_const_literal_test.cc
reader/wgsl/parser_impl_continue_stmt_test.cc
reader/wgsl/parser_impl_continuing_stmt_test.cc
@@ -1103,7 +1093,7 @@
transform/module_scope_var_to_entry_point_param_test.cc
transform/multiplanar_external_texture_test.cc
transform/num_workgroups_from_uniform_test.cc
- transform/promote_initializers_to_const_var_test.cc
+ transform/promote_initializers_to_let_test.cc
transform/promote_side_effects_to_decl_test.cc
transform/remove_continue_in_switch_test.cc
transform/remove_phonies_test.cc
@@ -1112,6 +1102,7 @@
transform/robustness_test.cc
transform/simplify_pointers_test.cc
transform/single_entry_point_test.cc
+ transform/spirv_atomic_test.cc
transform/test_helper.h
transform/unshadow_test.cc
transform/unwind_discard_functions_test.cc
@@ -1119,7 +1110,6 @@
transform/vectorize_scalar_matrix_constructors_test.cc
transform/vertex_pulling_test.cc
transform/while_to_loop_test.cc
- transform/wrap_arrays_in_structs_test.cc
transform/zero_init_workgroup_memory_test.cc
transform/utils/get_insertion_point_test.cc
transform/utils/hoist_to_decl_before_test.cc
diff --git a/src/tint/ast/array_test.cc b/src/tint/ast/array_test.cc
index baed079..f396e0c 100644
--- a/src/tint/ast/array_test.cc
+++ b/src/tint/ast/array_test.cc
@@ -62,7 +62,7 @@
TEST_F(AstArrayTest, FriendlyName_WithStride) {
auto* i32 = create<I32>();
- auto* arr = create<Array>(i32, Expr(5_u), AttributeList{create<StrideAttribute>(32)});
+ auto* arr = create<Array>(i32, Expr(5_u), AttributeList{create<StrideAttribute>(32u)});
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array<i32, 5>");
}
diff --git a/src/tint/ast/binding_attribute_test.cc b/src/tint/ast/binding_attribute_test.cc
index f51fc25..8000933 100644
--- a/src/tint/ast/binding_attribute_test.cc
+++ b/src/tint/ast/binding_attribute_test.cc
@@ -20,7 +20,7 @@
using BindingAttributeTest = TestHelper;
TEST_F(BindingAttributeTest, Creation) {
- auto* d = create<BindingAttribute>(2);
+ auto* d = create<BindingAttribute>(2u);
EXPECT_EQ(2u, d->value);
}
diff --git a/src/tint/ast/builtin_texture_helper_test.cc b/src/tint/ast/builtin_texture_helper_test.cc
index 21cbd93..ad42267 100644
--- a/src/tint/ast/builtin_texture_helper_test.cc
+++ b/src/tint/ast/builtin_texture_helper_test.cc
@@ -142,30 +142,31 @@
const ast::Variable* TextureOverloadCase::BuildTextureVariable(ProgramBuilder* b) const {
AttributeList attrs = {
- b->create<ast::GroupAttribute>(0),
- b->create<ast::BindingAttribute>(0),
+ b->create<ast::GroupAttribute>(0u),
+ b->create<ast::BindingAttribute>(0u),
};
switch (texture_kind) {
case ast::builtin::test::TextureKind::kRegular:
- return b->Global(
+ return b->GlobalVar(
"texture",
b->ty.sampled_texture(texture_dimension, BuildResultVectorComponentType(b)), attrs);
case ast::builtin::test::TextureKind::kDepth:
- return b->Global("texture", b->ty.depth_texture(texture_dimension), attrs);
+ return b->GlobalVar("texture", b->ty.depth_texture(texture_dimension), attrs);
case ast::builtin::test::TextureKind::kDepthMultisampled:
- return b->Global("texture", b->ty.depth_multisampled_texture(texture_dimension), attrs);
+ return b->GlobalVar("texture", b->ty.depth_multisampled_texture(texture_dimension),
+ attrs);
case ast::builtin::test::TextureKind::kMultisampled:
- return b->Global(
+ return b->GlobalVar(
"texture",
b->ty.multisampled_texture(texture_dimension, BuildResultVectorComponentType(b)),
attrs);
case ast::builtin::test::TextureKind::kStorage: {
auto* st = b->ty.storage_texture(texture_dimension, texel_format, access);
- return b->Global("texture", st, attrs);
+ return b->GlobalVar("texture", st, attrs);
}
}
@@ -175,10 +176,10 @@
const ast::Variable* TextureOverloadCase::BuildSamplerVariable(ProgramBuilder* b) const {
AttributeList attrs = {
- b->create<ast::GroupAttribute>(0),
- b->create<ast::BindingAttribute>(1),
+ b->create<ast::GroupAttribute>(0u),
+ b->create<ast::BindingAttribute>(1u),
};
- return b->Global("sampler", b->ty.sampler(sampler_kind), attrs);
+ return b->GlobalVar("sampler", b->ty.sampler(sampler_kind), attrs);
}
std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
diff --git a/src/tint/ast/const.cc b/src/tint/ast/const.cc
new file mode 100644
index 0000000..e13cc25
--- /dev/null
+++ b/src/tint/ast/const.cc
@@ -0,0 +1,50 @@
+// 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/ast/const.h"
+
+#include "src/tint/program_builder.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::ast::Const);
+
+namespace tint::ast {
+
+Const::Const(ProgramID pid,
+ const Source& src,
+ const Symbol& sym,
+ const ast::Type* ty,
+ const Expression* ctor,
+ AttributeList attrs)
+ : Base(pid, src, sym, ty, ctor, attrs) {
+ TINT_ASSERT(AST, ctor != nullptr);
+}
+
+Const::Const(Const&&) = default;
+
+Const::~Const() = default;
+
+const char* Const::Kind() const {
+ return "const";
+}
+
+const Const* Const::Clone(CloneContext* ctx) const {
+ auto src = ctx->Clone(source);
+ auto sym = ctx->Clone(symbol);
+ auto* ty = ctx->Clone(type);
+ auto* ctor = ctx->Clone(constructor);
+ auto attrs = ctx->Clone(attributes);
+ return ctx->dst->create<Const>(src, sym, ty, ctor, attrs);
+}
+
+} // namespace tint::ast
diff --git a/src/tint/ast/const.h b/src/tint/ast/const.h
new file mode 100644
index 0000000..32e3ddd
--- /dev/null
+++ b/src/tint/ast/const.h
@@ -0,0 +1,67 @@
+// 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_AST_CONST_H_
+#define SRC_TINT_AST_CONST_H_
+
+#include "src/tint/ast/variable.h"
+
+namespace tint::ast {
+
+/// A "const" declaration is a name for a module-scoped or function-scoped creation-time value.
+/// const must have a constructor expression.
+///
+/// Examples:
+///
+/// ```
+/// const n = 123; // Abstract-integer typed constant
+/// const pi = 3.14159265359; // Abstract-float typed constant
+/// const max_f32 : f32 = 0x1.fffffep+127; // f32 typed constant
+/// ```
+/// @see https://www.w3.org/TR/WGSL/#creation-time-consts
+class Const final : public Castable<Const, Variable> {
+ public:
+ /// Create a 'const' creation-time value variable.
+ /// @param program_id the identifier of the program that owns this node
+ /// @param source the variable source
+ /// @param sym the variable symbol
+ /// @param type the declared variable type
+ /// @param constructor the constructor expression. Must not be nullptr.
+ /// @param attributes the variable attributes
+ Const(ProgramID program_id,
+ const Source& source,
+ const Symbol& sym,
+ const ast::Type* type,
+ const Expression* constructor,
+ AttributeList attributes);
+
+ /// Move constructor
+ Const(Const&&);
+
+ /// Destructor
+ ~Const() override;
+
+ /// @returns "const"
+ const char* Kind() const override;
+
+ /// Clones this node and all transitive child nodes using the `CloneContext`
+ /// `ctx`.
+ /// @param ctx the clone context
+ /// @return the newly cloned node
+ const Const* Clone(CloneContext* ctx) const override;
+};
+
+} // namespace tint::ast
+
+#endif // SRC_TINT_AST_CONST_H_
diff --git a/src/tint/ast/group_attribute_test.cc b/src/tint/ast/group_attribute_test.cc
index 53167bb..4a6dd1d 100644
--- a/src/tint/ast/group_attribute_test.cc
+++ b/src/tint/ast/group_attribute_test.cc
@@ -20,7 +20,7 @@
using GroupAttributeTest = TestHelper;
TEST_F(GroupAttributeTest, Creation) {
- auto* d = create<GroupAttribute>(2);
+ auto* d = create<GroupAttribute>(2u);
EXPECT_EQ(2u, d->value);
}
diff --git a/src/tint/ast/id_attribute_test.cc b/src/tint/ast/id_attribute_test.cc
index 6957d66..ad05c58 100644
--- a/src/tint/ast/id_attribute_test.cc
+++ b/src/tint/ast/id_attribute_test.cc
@@ -22,7 +22,7 @@
using IdAttributeTest = TestHelper;
TEST_F(IdAttributeTest, Creation) {
- auto* d = create<IdAttribute>(12);
+ auto* d = create<IdAttribute>(12u);
EXPECT_EQ(12u, d->value);
}
diff --git a/src/tint/ast/let.cc b/src/tint/ast/let.cc
index e771c4d..8db8ec1 100644
--- a/src/tint/ast/let.cc
+++ b/src/tint/ast/let.cc
@@ -34,6 +34,10 @@
Let::~Let() = default;
+const char* Let::Kind() const {
+ return "let";
+}
+
const Let* Let::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto sym = ctx->Clone(symbol);
diff --git a/src/tint/ast/let.h b/src/tint/ast/let.h
index 2b0a6aa..2c1ad7c 100644
--- a/src/tint/ast/let.h
+++ b/src/tint/ast/let.h
@@ -49,6 +49,9 @@
/// Destructor
~Let() override;
+ /// @returns "let"
+ const char* Kind() const override;
+
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
diff --git a/src/tint/ast/location_attribute_test.cc b/src/tint/ast/location_attribute_test.cc
index a1562d5..e0bcb39 100644
--- a/src/tint/ast/location_attribute_test.cc
+++ b/src/tint/ast/location_attribute_test.cc
@@ -20,7 +20,7 @@
using LocationAttributeTest = TestHelper;
TEST_F(LocationAttributeTest, Creation) {
- auto* d = create<LocationAttribute>(2);
+ auto* d = create<LocationAttribute>(2u);
EXPECT_EQ(2u, d->value);
}
diff --git a/src/tint/ast/matrix_test.cc b/src/tint/ast/matrix_test.cc
index 66ea84d..dbb88e3 100644
--- a/src/tint/ast/matrix_test.cc
+++ b/src/tint/ast/matrix_test.cc
@@ -34,7 +34,7 @@
TEST_F(AstMatrixTest, Creation) {
auto* i32 = create<I32>();
- auto* m = create<Matrix>(i32, 2, 4);
+ auto* m = create<Matrix>(i32, 2u, 4u);
EXPECT_EQ(m->type, i32);
EXPECT_EQ(m->rows, 2u);
EXPECT_EQ(m->columns, 4u);
@@ -42,12 +42,12 @@
TEST_F(AstMatrixTest, FriendlyName) {
auto* i32 = create<I32>();
- auto* m = create<Matrix>(i32, 3, 2);
+ auto* m = create<Matrix>(i32, 3u, 2u);
EXPECT_EQ(m->FriendlyName(Symbols()), "mat2x3<i32>");
}
TEST_F(AstMatrixTest, FriendlyName_WithoutType) {
- auto* m = create<Matrix>(nullptr, 3, 2);
+ auto* m = create<Matrix>(nullptr, 3u, 2u);
EXPECT_EQ(m->FriendlyName(Symbols()), "mat2x3");
}
diff --git a/src/tint/ast/module_clone_test.cc b/src/tint/ast/module_clone_test.cc
index bd96b26..544e6bf 100644
--- a/src/tint/ast/module_clone_test.cc
+++ b/src/tint/ast/module_clone_test.cc
@@ -37,8 +37,8 @@
m1 : array<u32, 6>,
};
-let c0 : i32 = 10;
-let c1 : bool = true;
+const c0 : i32 = 10;
+const c1 : bool = true;
type t0 = array<vec4<f32>>;
type t1 = array<vec4<f32>>;
@@ -71,6 +71,8 @@
var l4 : S1;
var l5 : u32 = l4.m1[5];
let l6 : ptr<private, u32> = &g0;
+ const l7 = 123;
+ const l8 : i32 = 123;
loop {
l0 = (p1 + 2);
if (((l0 % 4) == 0)) {
@@ -104,7 +106,7 @@
f1(1.0, 2);
}
-let declaration_order_check_0 : i32 = 1;
+const declaration_order_check_0 : i32 = 1;
type declaration_order_check_1 = f32;
@@ -112,7 +114,7 @@
type declaration_order_check_3 = f32;
-let declaration_order_check_4 : i32 = 1;
+const declaration_order_check_4 : i32 = 1;
)");
diff --git a/src/tint/ast/module_test.cc b/src/tint/ast/module_test.cc
index 4a2884b..7096769 100644
--- a/src/tint/ast/module_test.cc
+++ b/src/tint/ast/module_test.cc
@@ -92,7 +92,7 @@
ProgramBuilder b;
b.Func("F", {}, b.ty.void_(), {});
b.Alias("A", b.ty.u32());
- b.Global("V", b.ty.i32(), ast::StorageClass::kPrivate);
+ b.GlobalVar("V", b.ty.i32(), ast::StorageClass::kPrivate);
return Program(std::move(b));
}();
diff --git a/src/tint/ast/override.cc b/src/tint/ast/override.cc
index f494bc8..efd048d 100644
--- a/src/tint/ast/override.cc
+++ b/src/tint/ast/override.cc
@@ -32,6 +32,10 @@
Override::~Override() = default;
+const char* Override::Kind() const {
+ return "override";
+}
+
const Override* Override::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto sym = ctx->Clone(symbol);
diff --git a/src/tint/ast/override.h b/src/tint/ast/override.h
index 168b9b2..98319e5 100644
--- a/src/tint/ast/override.h
+++ b/src/tint/ast/override.h
@@ -50,6 +50,9 @@
/// Destructor
~Override() override;
+ /// @returns "override"
+ const char* Kind() const override;
+
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
diff --git a/src/tint/ast/parameter.cc b/src/tint/ast/parameter.cc
index b7ea3b1..ea3c51f 100644
--- a/src/tint/ast/parameter.cc
+++ b/src/tint/ast/parameter.cc
@@ -31,6 +31,10 @@
Parameter::~Parameter() = default;
+const char* Parameter::Kind() const {
+ return "parameter";
+}
+
const Parameter* Parameter::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto sym = ctx->Clone(symbol);
diff --git a/src/tint/ast/parameter.h b/src/tint/ast/parameter.h
index d3ecf8d..eb4b688 100644
--- a/src/tint/ast/parameter.h
+++ b/src/tint/ast/parameter.h
@@ -51,6 +51,9 @@
/// Destructor
~Parameter() override;
+ /// @returns "parameter"
+ const char* Kind() const override;
+
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
diff --git a/src/tint/ast/stride_attribute_test.cc b/src/tint/ast/stride_attribute_test.cc
index 61c4fb5..eb19034 100644
--- a/src/tint/ast/stride_attribute_test.cc
+++ b/src/tint/ast/stride_attribute_test.cc
@@ -20,13 +20,13 @@
using StrideAttributeTest = TestHelper;
TEST_F(StrideAttributeTest, Creation) {
- auto* d = create<StrideAttribute>(2);
+ auto* d = create<StrideAttribute>(2u);
EXPECT_EQ(2u, d->stride);
}
TEST_F(StrideAttributeTest, Source) {
auto* d = create<StrideAttribute>(
- Source{Source::Range{Source::Location{1, 2}, Source::Location{3, 4}}}, 2);
+ Source{Source::Range{Source::Location{1, 2}, Source::Location{3, 4}}}, 2u);
EXPECT_EQ(d->source.range.begin.line, 1u);
EXPECT_EQ(d->source.range.begin.column, 2u);
EXPECT_EQ(d->source.range.end.line, 3u);
diff --git a/src/tint/ast/struct_member_align_attribute_test.cc b/src/tint/ast/struct_member_align_attribute_test.cc
index 5b4ff48..ba4d1bb 100644
--- a/src/tint/ast/struct_member_align_attribute_test.cc
+++ b/src/tint/ast/struct_member_align_attribute_test.cc
@@ -22,7 +22,7 @@
using StructMemberAlignAttributeTest = TestHelper;
TEST_F(StructMemberAlignAttributeTest, Creation) {
- auto* d = create<StructMemberAlignAttribute>(2);
+ auto* d = create<StructMemberAlignAttribute>(2u);
EXPECT_EQ(2u, d->align);
}
diff --git a/src/tint/ast/struct_member_offset_attribute_test.cc b/src/tint/ast/struct_member_offset_attribute_test.cc
index 3c0eb41..9d81ffb 100644
--- a/src/tint/ast/struct_member_offset_attribute_test.cc
+++ b/src/tint/ast/struct_member_offset_attribute_test.cc
@@ -20,7 +20,7 @@
using StructMemberOffsetAttributeTest = TestHelper;
TEST_F(StructMemberOffsetAttributeTest, Creation) {
- auto* d = create<StructMemberOffsetAttribute>(2);
+ auto* d = create<StructMemberOffsetAttribute>(2u);
EXPECT_EQ(2u, d->offset);
}
diff --git a/src/tint/ast/struct_member_size_attribute_test.cc b/src/tint/ast/struct_member_size_attribute_test.cc
index a9d4637..a82d53a 100644
--- a/src/tint/ast/struct_member_size_attribute_test.cc
+++ b/src/tint/ast/struct_member_size_attribute_test.cc
@@ -22,7 +22,7 @@
using StructMemberSizeAttributeTest = TestHelper;
TEST_F(StructMemberSizeAttributeTest, Creation) {
- auto* d = create<StructMemberSizeAttribute>(2);
+ auto* d = create<StructMemberSizeAttribute>(2u);
EXPECT_EQ(2u, d->size);
}
diff --git a/src/tint/ast/var.cc b/src/tint/ast/var.cc
index 622aa03..854503e 100644
--- a/src/tint/ast/var.cc
+++ b/src/tint/ast/var.cc
@@ -36,6 +36,10 @@
Var::~Var() = default;
+const char* Var::Kind() const {
+ return "var";
+}
+
const Var* Var::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
auto sym = ctx->Clone(symbol);
diff --git a/src/tint/ast/var.h b/src/tint/ast/var.h
index fd03580..565ebbb 100644
--- a/src/tint/ast/var.h
+++ b/src/tint/ast/var.h
@@ -65,6 +65,9 @@
/// Destructor
~Var() override;
+ /// @returns "var"
+ const char* Kind() const override;
+
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
diff --git a/src/tint/ast/variable.h b/src/tint/ast/variable.h
index bc25753..631fbe5 100644
--- a/src/tint/ast/variable.h
+++ b/src/tint/ast/variable.h
@@ -77,6 +77,10 @@
/// @note binding points should only be applied to Var and Parameter types.
VariableBindingPoint BindingPoint() const;
+ /// @returns the kind of the variable, which can be used in diagnostics
+ /// e.g. "var", "let", "const", etc
+ virtual const char* Kind() const = 0;
+
/// The variable symbol
const Symbol symbol;
diff --git a/src/tint/ast/variable_test.cc b/src/tint/ast/variable_test.cc
index e62ec1e..025fa6b 100644
--- a/src/tint/ast/variable_test.cc
+++ b/src/tint/ast/variable_test.cc
@@ -94,9 +94,9 @@
TEST_F(VariableTest, WithAttributes) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
AttributeList{
- create<LocationAttribute>(1),
+ create<LocationAttribute>(1u),
create<BuiltinAttribute>(Builtin::kPosition),
- create<IdAttribute>(1200),
+ create<IdAttribute>(1200u),
});
auto& attributes = var->attributes;
@@ -112,8 +112,8 @@
TEST_F(VariableTest, BindingPoint) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
AttributeList{
- create<BindingAttribute>(2),
- create<GroupAttribute>(1),
+ create<BindingAttribute>(2u),
+ create<GroupAttribute>(1u),
});
EXPECT_TRUE(var->BindingPoint());
ASSERT_NE(var->BindingPoint().binding, nullptr);
@@ -132,7 +132,7 @@
TEST_F(VariableTest, BindingPointMissingGroupAttribute) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
AttributeList{
- create<BindingAttribute>(2),
+ create<BindingAttribute>(2u),
});
EXPECT_FALSE(var->BindingPoint());
ASSERT_NE(var->BindingPoint().binding, nullptr);
@@ -142,7 +142,7 @@
TEST_F(VariableTest, BindingPointMissingBindingAttribute) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
- AttributeList{create<GroupAttribute>(1)});
+ AttributeList{create<GroupAttribute>(1u)});
EXPECT_FALSE(var->BindingPoint());
ASSERT_NE(var->BindingPoint().group, nullptr);
EXPECT_EQ(var->BindingPoint().group->value, 1u);
diff --git a/src/tint/ast/vector_test.cc b/src/tint/ast/vector_test.cc
index a701852..da2ad1f 100644
--- a/src/tint/ast/vector_test.cc
+++ b/src/tint/ast/vector_test.cc
@@ -24,14 +24,14 @@
TEST_F(AstVectorTest, Creation) {
auto* i32 = create<I32>();
- auto* v = create<Vector>(i32, 2);
+ auto* v = create<Vector>(i32, 2u);
EXPECT_EQ(v->type, i32);
EXPECT_EQ(v->width, 2u);
}
TEST_F(AstVectorTest, FriendlyName) {
auto* f32 = create<F32>();
- auto* v = create<Vector>(f32, 3);
+ auto* v = create<Vector>(f32, 3u);
EXPECT_EQ(v->FriendlyName(Symbols()), "vec3<f32>");
}
diff --git a/src/tint/castable.cc b/src/tint/castable.cc
index cff430e..40c32da 100644
--- a/src/tint/castable.cc
+++ b/src/tint/castable.cc
@@ -26,4 +26,8 @@
tint::TypeInfo::FullHashCodeOf<CastableBase>(),
};
+CastableBase::CastableBase(const CastableBase&) = default;
+
+CastableBase::~CastableBase() = default;
+
} // namespace tint
diff --git a/src/tint/castable.h b/src/tint/castable.h
index 048d1e5..c7b8608 100644
--- a/src/tint/castable.h
+++ b/src/tint/castable.h
@@ -320,10 +320,10 @@
class CastableBase {
public:
/// Copy constructor
- CastableBase(const CastableBase&) = default;
+ CastableBase(const CastableBase&);
/// Destructor
- virtual ~CastableBase() = default;
+ virtual ~CastableBase();
/// Copy assignment
/// @param other the CastableBase to copy
@@ -626,7 +626,7 @@
// Static assertions
static constexpr bool kDefaultIsOK =
- kDefaultIndex == -1 || kDefaultIndex == std::tuple_size_v<Cases> - 1;
+ kDefaultIndex == -1 || kDefaultIndex == static_cast<int>(std::tuple_size_v<Cases> - 1);
static constexpr bool kReturnIsOK =
kHasDefaultCase || !kHasReturnType || std::is_constructible_v<RETURN_TYPE>;
static_assert(kDefaultIsOK, "Default case must be last in Switch()");
diff --git a/src/tint/clone_context.cc b/src/tint/clone_context.cc
index 0a9e606..513c710 100644
--- a/src/tint/clone_context.cc
+++ b/src/tint/clone_context.cc
@@ -23,6 +23,10 @@
namespace tint {
+Cloneable::Cloneable() = default;
+Cloneable::Cloneable(Cloneable&&) = default;
+Cloneable::~Cloneable() = default;
+
CloneContext::ListTransforms::ListTransforms() = default;
CloneContext::ListTransforms::~ListTransforms() = default;
diff --git a/src/tint/clone_context.h b/src/tint/clone_context.h
index 887d628..e8e197f 100644
--- a/src/tint/clone_context.h
+++ b/src/tint/clone_context.h
@@ -48,6 +48,13 @@
/// Cloneable is the base class for all objects that can be cloned
class Cloneable : public Castable<Cloneable> {
public:
+ /// Constructor
+ Cloneable();
+ /// Move constructor
+ Cloneable(Cloneable&&);
+ /// Destructor
+ ~Cloneable() override;
+
/// Performs a deep clone of this object using the CloneContext `ctx`.
/// @param ctx the clone context
/// @return the newly cloned object
diff --git a/src/tint/demangler.cc b/src/tint/demangler.cc
index 0116be0..d68a62a 100644
--- a/src/tint/demangler.cc
+++ b/src/tint/demangler.cc
@@ -49,7 +49,7 @@
auto len = end_idx - start_idx;
auto id = str.substr(start_idx, len);
- Symbol sym(std::stoi(id), symbols.ProgramID());
+ Symbol sym(static_cast<uint32_t>(std::stoi(id)), symbols.ProgramID());
out << symbols.NameFor(sym);
pos = end_idx;
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_unary_operators.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_unary_operators.cc
index ed2f442..fb3fb96 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_unary_operators.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_unary_operators.cc
@@ -16,6 +16,7 @@
#include <memory>
+#include "src/tint/ast/unary_op_expression.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/util.h"
#include "src/tint/sem/reference.h"
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_binary_operator.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_binary_operator.cc
index d27fa7f..6e78cb5 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_binary_operator.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_binary_operator.cc
@@ -16,6 +16,8 @@
#include <utility>
+#include "src/tint/program_builder.h"
+#include "src/tint/sem/bool.h"
#include "src/tint/sem/reference.h"
namespace tint::fuzzers::ast_fuzzer {
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator.h b/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator.h
index d80ec3f..1fa84a8 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator.h
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator.h
@@ -15,6 +15,7 @@
#ifndef SRC_TINT_FUZZERS_TINT_AST_FUZZER_MUTATIONS_CHANGE_UNARY_OPERATOR_H_
#define SRC_TINT_FUZZERS_TINT_AST_FUZZER_MUTATIONS_CHANGE_UNARY_OPERATOR_H_
+#include "src/tint/ast/unary_op.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/mutation.h"
#include "src/tint/sem/variable.h"
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.h b/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.h
index ec28bf9..96d0926 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.h
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.h
@@ -19,6 +19,7 @@
#include "src/tint/fuzzers/tint_ast_fuzzer/mutation.h"
+#include "src/tint/ast/unary_op.h"
#include "src/tint/sem/variable.h"
namespace tint::fuzzers::ast_fuzzer {
diff --git a/src/tint/inspector/inspector.cc b/src/tint/inspector/inspector.cc
index df208f6..c5b3eb7 100644
--- a/src/tint/inspector/inspector.cc
+++ b/src/tint/inspector/inspector.cc
@@ -22,12 +22,17 @@
#include "src/tint/ast/extension.h"
#include "src/tint/ast/float_literal_expression.h"
#include "src/tint/ast/id_attribute.h"
+#include "src/tint/ast/int_literal_expression.h"
#include "src/tint/ast/interpolate_attribute.h"
#include "src/tint/ast/location_attribute.h"
#include "src/tint/ast/module.h"
+#include "src/tint/ast/override.h"
+#include "src/tint/ast/var.h"
#include "src/tint/sem/array.h"
#include "src/tint/sem/call.h"
#include "src/tint/sem/depth_multisampled_texture.h"
+#include "src/tint/sem/depth_texture.h"
+#include "src/tint/sem/external_texture.h"
#include "src/tint/sem/f16.h"
#include "src/tint/sem/f32.h"
#include "src/tint/sem/function.h"
@@ -810,8 +815,8 @@
continue;
}
- auto* t = c->args[texture_index];
- auto* s = c->args[sampler_index];
+ auto* t = c->args[static_cast<size_t>(texture_index)];
+ auto* s = c->args[static_cast<size_t>(sampler_index)];
GetOriginatingResources(
std::array<const ast::Expression*, 2>{t, s},
diff --git a/src/tint/inspector/inspector_test.cc b/src/tint/inspector/inspector_test.cc
index fb09522..4e369d5 100644
--- a/src/tint/inspector/inspector_test.cc
+++ b/src/tint/inspector/inspector_test.cc
@@ -3048,7 +3048,7 @@
// here the struct is expected to occupy 1024 bytes of workgroup storage.
const auto* wg_struct_type = MakeStructTypeFromMembers(
"WgStruct",
- {MakeStructMember(0, ty.f32(), {create<ast::StructMemberAlignAttribute>(1024)})});
+ {MakeStructMember(0, ty.f32(), {create<ast::StructMemberAlignAttribute>(1024u)})});
AddWorkgroupStorage("wg_struct_var", ty.Of(wg_struct_type));
MakeStructVariableReferenceBodyFunction("wg_struct_func", "wg_struct_var", {{0, ty.f32()}});
diff --git a/src/tint/inspector/test_inspector_builder.cc b/src/tint/inspector/test_inspector_builder.cc
index 949ee75..23b473c 100644
--- a/src/tint/inspector/test_inspector_builder.cc
+++ b/src/tint/inspector/test_inspector_builder.cc
@@ -121,15 +121,15 @@
const ast::Type* type,
uint32_t group,
uint32_t binding) {
- Global(name, type, ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(binding),
- create<ast::GroupAttribute>(group),
- });
+ GlobalVar(name, type, ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(binding),
+ create<ast::GroupAttribute>(group),
+ });
}
void InspectorBuilder::AddWorkgroupStorage(const std::string& name, const ast::Type* type) {
- Global(name, type, ast::StorageClass::kWorkgroup);
+ GlobalVar(name, type, ast::StorageClass::kWorkgroup);
}
void InspectorBuilder::AddStorageBuffer(const std::string& name,
@@ -137,11 +137,11 @@
ast::Access access,
uint32_t group,
uint32_t binding) {
- Global(name, type, ast::StorageClass::kStorage, access,
- ast::AttributeList{
- create<ast::BindingAttribute>(binding),
- create<ast::GroupAttribute>(group),
- });
+ GlobalVar(name, type, ast::StorageClass::kStorage, access,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(binding),
+ create<ast::GroupAttribute>(group),
+ });
}
void InspectorBuilder::MakeStructVariableReferenceBodyFunction(
@@ -173,36 +173,36 @@
}
void InspectorBuilder::AddSampler(const std::string& name, uint32_t group, uint32_t binding) {
- Global(name, sampler_type(),
- ast::AttributeList{
- create<ast::BindingAttribute>(binding),
- create<ast::GroupAttribute>(group),
- });
+ GlobalVar(name, sampler_type(),
+ ast::AttributeList{
+ create<ast::BindingAttribute>(binding),
+ create<ast::GroupAttribute>(group),
+ });
}
void InspectorBuilder::AddComparisonSampler(const std::string& name,
uint32_t group,
uint32_t binding) {
- Global(name, comparison_sampler_type(),
- ast::AttributeList{
- create<ast::BindingAttribute>(binding),
- create<ast::GroupAttribute>(group),
- });
+ GlobalVar(name, comparison_sampler_type(),
+ ast::AttributeList{
+ create<ast::BindingAttribute>(binding),
+ create<ast::GroupAttribute>(group),
+ });
}
void InspectorBuilder::AddResource(const std::string& name,
const ast::Type* type,
uint32_t group,
uint32_t binding) {
- Global(name, type,
- ast::AttributeList{
- create<ast::BindingAttribute>(binding),
- create<ast::GroupAttribute>(group),
- });
+ GlobalVar(name, type,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(binding),
+ create<ast::GroupAttribute>(group),
+ });
}
void InspectorBuilder::AddGlobalVariable(const std::string& name, const ast::Type* type) {
- Global(name, type, ast::StorageClass::kPrivate);
+ GlobalVar(name, type, ast::StorageClass::kPrivate);
}
const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
@@ -285,11 +285,11 @@
return scalar;
case ast::TextureDimension::k2d:
case ast::TextureDimension::k2dArray:
- return create<ast::Vector>(scalar, 2);
+ return create<ast::Vector>(scalar, 2u);
case ast::TextureDimension::k3d:
case ast::TextureDimension::kCube:
case ast::TextureDimension::kCubeArray:
- return create<ast::Vector>(scalar, 3);
+ return create<ast::Vector>(scalar, 3u);
default:
[=]() { FAIL() << "Unsupported texture dimension: " << dim; }();
}
@@ -305,11 +305,11 @@
const ast::Type* type,
uint32_t group,
uint32_t binding) {
- Global(name, type,
- ast::AttributeList{
- create<ast::BindingAttribute>(binding),
- create<ast::GroupAttribute>(group),
- });
+ GlobalVar(name, type,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(binding),
+ create<ast::GroupAttribute>(group),
+ });
}
const ast::Function* InspectorBuilder::MakeStorageTextureBodyFunction(
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index f74639d..17ce925 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -71,11 +71,12 @@
// https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section
type bool
-@precedence(4) @display("abstract-float") type af
-@precedence(3) @display("abstract-int") type ai
-@precedence(2) type i32
-@precedence(1) type u32
-@precedence(0) type f32
+@precedence(5) @display("abstract-float") type af
+@precedence(4) @display("abstract-int") type ai
+@precedence(3) type i32
+@precedence(2) type u32
+@precedence(1) type f32
+@precedence(0) type f16
type vec2<T>
type vec3<T>
type vec4<T>
@@ -126,16 +127,19 @@
// A type matcher that can match one or more types. //
////////////////////////////////////////////////////////////////////////////////
+match f32f16: f32 | f16
match fiu32: f32 | i32 | u32
match fi32: f32 | i32
match iu32: i32 | u32
-match scalar: f32 | i32 | u32 | bool
-match abstract_or_scalar: ai | af | f32 | i32 | u32 | bool
+match scalar: f32 | f16 | i32 | u32 | bool
+match abstract_or_scalar: ai | af | f32 | f16 | i32 | u32 | bool
match af_f32: af | f32
-match scalar_no_f32: i32 | u32 | bool
-match scalar_no_i32: f32 | u32 | bool
-match scalar_no_u32: f32 | i32 | bool
-match scalar_no_bool: f32 | i32 | u32
+match af_f32f16: af | f32 | f16
+match scalar_no_f32: i32 | f16 | u32 | bool
+match scalar_no_f16: f32 | i32 | u32 | bool
+match scalar_no_i32: f32 | f16 | u32 | bool
+match scalar_no_u32: f32 | f16 | i32 | bool
+match scalar_no_bool: f32 | f16 | i32 | u32
////////////////////////////////////////////////////////////////////////////////
// Enum matchers //
@@ -329,6 +333,8 @@
fn abs<N: num, T: fiu32>(vec<N, T>) -> vec<N, T>
fn acos(f32) -> f32
fn acos<N: num>(vec<N, f32>) -> vec<N, f32>
+fn acosh(f32) -> f32
+fn acosh<N: num>(vec<N, f32>) -> vec<N, f32>
fn all(bool) -> bool
fn all<N: num>(vec<N, bool>) -> bool
fn any(bool) -> bool
@@ -336,10 +342,14 @@
fn arrayLength<T, A: access>(ptr<storage, array<T>, A>) -> u32
fn asin(f32) -> f32
fn asin<N: num>(vec<N, f32>) -> vec<N, f32>
+fn asinh(f32) -> f32
+fn asinh<N: num>(vec<N, f32>) -> vec<N, f32>
fn atan(f32) -> f32
fn atan<N: num>(vec<N, f32>) -> vec<N, f32>
fn atan2(f32, f32) -> f32
fn atan2<N: num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32>
+fn atanh(f32) -> f32
+fn atanh<N: num>(vec<N, f32>) -> vec<N, f32>
fn ceil(f32) -> f32
fn ceil<N: num>(vec<N, f32>) -> vec<N, f32>
fn clamp<T: fiu32>(T, T, T) -> T
@@ -437,9 +447,9 @@
fn reverseBits<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
fn round(f32) -> f32
fn round<N: num>(vec<N, f32>) -> vec<N, f32>
-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>
+fn select<T: scalar_no_f16>(T, T, bool) -> T
+fn select<T: scalar_no_f16, N: num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T>
+fn select<N: num, T: scalar_no_f16>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T>
fn sign(f32) -> f32
fn sign<N: num>(vec<N, f32>) -> vec<N, f32>
fn sin(f32) -> f32
@@ -629,37 +639,39 @@
ctor i32() -> i32
ctor u32() -> u32
ctor f32() -> f32
+ctor f16() -> f16
ctor bool() -> bool
ctor vec2<T: scalar>() -> vec2<T>
ctor vec3<T: scalar>() -> vec3<T>
ctor vec4<T: scalar>() -> vec4<T>
-ctor mat2x2() -> mat2x2<f32>
-ctor mat2x3() -> mat2x3<f32>
-ctor mat2x4() -> mat2x4<f32>
-ctor mat3x2() -> mat3x2<f32>
-ctor mat3x3() -> mat3x3<f32>
-ctor mat3x4() -> mat3x4<f32>
-ctor mat4x2() -> mat4x2<f32>
-ctor mat4x3() -> mat4x3<f32>
-ctor mat4x4() -> mat4x4<f32>
+ctor mat2x2<T: f32f16>() -> mat2x2<T>
+ctor mat2x3<T: f32f16>() -> mat2x3<T>
+ctor mat2x4<T: f32f16>() -> mat2x4<T>
+ctor mat3x2<T: f32f16>() -> mat3x2<T>
+ctor mat3x3<T: f32f16>() -> mat3x3<T>
+ctor mat3x4<T: f32f16>() -> mat3x4<T>
+ctor mat4x2<T: f32f16>() -> mat4x2<T>
+ctor mat4x3<T: f32f16>() -> mat4x3<T>
+ctor mat4x4<T: f32f16>() -> mat4x4<T>
// Identity constructors
ctor i32(i32) -> i32
ctor u32(u32) -> u32
ctor f32(f32) -> f32
+ctor f16(f16) -> f16
ctor bool(bool) -> bool
ctor vec2<T: scalar>(vec2<T>) -> vec2<T>
ctor vec3<T: scalar>(vec3<T>) -> vec3<T>
ctor vec4<T: scalar>(vec4<T>) -> vec4<T>
-ctor mat2x2<f32>(mat2x2<f32>) -> mat2x2<f32>
-ctor mat2x3<f32>(mat2x3<f32>) -> mat2x3<f32>
-ctor mat2x4<f32>(mat2x4<f32>) -> mat2x4<f32>
-ctor mat3x2<f32>(mat3x2<f32>) -> mat3x2<f32>
-ctor mat3x3<f32>(mat3x3<f32>) -> mat3x3<f32>
-ctor mat3x4<f32>(mat3x4<f32>) -> mat3x4<f32>
-ctor mat4x2<f32>(mat4x2<f32>) -> mat4x2<f32>
-ctor mat4x3<f32>(mat4x3<f32>) -> mat4x3<f32>
-ctor mat4x4<f32>(mat4x4<f32>) -> mat4x4<f32>
+ctor mat2x2<T: f32f16>(mat2x2<T>) -> mat2x2<T>
+ctor mat2x3<T: f32f16>(mat2x3<T>) -> mat2x3<T>
+ctor mat2x4<T: f32f16>(mat2x4<T>) -> mat2x4<T>
+ctor mat3x2<T: f32f16>(mat3x2<T>) -> mat3x2<T>
+ctor mat3x3<T: f32f16>(mat3x3<T>) -> mat3x3<T>
+ctor mat3x4<T: f32f16>(mat3x4<T>) -> mat3x4<T>
+ctor mat4x2<T: f32f16>(mat4x2<T>) -> mat4x2<T>
+ctor mat4x3<T: f32f16>(mat4x3<T>) -> mat4x3<T>
+ctor mat4x4<T: f32f16>(mat4x4<T>) -> mat4x4<T>
// Vector constructors
ctor vec2<T: abstract_or_scalar>(T) -> vec2<T>
@@ -679,82 +691,106 @@
// Matrix constructors
ctor mat2x2<T: af_f32>(T) -> mat2x2<T>
-ctor mat2x2<T: af_f32>(T, T,
- T, T) -> mat2x2<T>
-ctor mat2x2<T: af_f32>(vec2<T>, vec2<T>) -> mat2x2<T>
-
ctor mat2x3<T: af_f32>(T) -> mat2x3<T>
-ctor mat2x3<T: af_f32>(T, T, T,
- T, T, T) -> mat2x3<T>
-ctor mat2x3<T: af_f32>(vec3<T>, vec3<T>) -> mat2x3<T>
-
ctor mat2x4<T: af_f32>(T) -> mat2x4<T>
-ctor mat2x4<T: af_f32>(T, T, T, T,
- T, T, T, T) -> mat2x4<T>
-ctor mat2x4<T: af_f32>(vec4<T>, vec4<T>) -> mat2x4<T>
-
ctor mat3x2<T: af_f32>(T) -> mat3x2<T>
-ctor mat3x2<T: af_f32>(T, T,
- T, T,
- T, T) -> mat3x2<T>
-ctor mat3x2<T: af_f32>(vec2<T>, vec2<T>, vec2<T>) -> mat3x2<T>
-
ctor mat3x3<T: af_f32>(T) -> mat3x3<T>
-ctor mat3x3<T: af_f32>(T, T, T,
- T, T, T,
- T, T, T) -> mat3x3<T>
-ctor mat3x3<T: af_f32>(vec3<T>, vec3<T>, vec3<T>) -> mat3x3<T>
-
ctor mat3x4<T: af_f32>(T) -> mat3x4<T>
-ctor mat3x4<T: af_f32>(T, T, T, T,
- T, T, T, T,
- T, T, T, T) -> mat3x4<T>
-ctor mat3x4<T: af_f32>(vec4<T>, vec4<T>, vec4<T>) -> mat3x4<T>
-
ctor mat4x2<T: af_f32>(T) -> mat4x2<T>
-ctor mat4x2<T: af_f32>(T, T,
- T, T,
- T, T,
- T, T) -> mat4x2<T>
-ctor mat4x2<T: af_f32>(vec2<T>, vec2<T>, vec2<T>, vec2<T>) -> mat4x2<T>
-
ctor mat4x3<T: af_f32>(T) -> mat4x3<T>
-ctor mat4x3<T: af_f32>(T, T, T,
- T, T, T,
- T, T, T,
- T, T, T) -> mat4x3<T>
-ctor mat4x3<T: af_f32>(vec3<T>, vec3<T>, vec3<T>, vec3<T>) -> mat4x3<T>
-
ctor mat4x4<T: af_f32>(T) -> mat4x4<T>
-ctor mat4x4<T: af_f32>(T, T, T, T,
- T, T, T, T,
- T, T, T, T,
- T, T, T, T) -> mat4x4<T>
-ctor mat4x4<T: af_f32>(vec4<T>, vec4<T>, vec4<T>, vec4<T>) -> mat4x4<T>
+
+ctor mat2x2<T: af_f32f16>(T, T,
+ T, T) -> mat2x2<T>
+ctor mat2x2<T: af_f32f16>(vec2<T>, vec2<T>) -> mat2x2<T>
+
+ctor mat2x3<T: af_f32f16>(T, T, T,
+ T, T, T) -> mat2x3<T>
+ctor mat2x3<T: af_f32f16>(vec3<T>, vec3<T>) -> mat2x3<T>
+
+ctor mat2x4<T: af_f32f16>(T, T, T, T,
+ T, T, T, T) -> mat2x4<T>
+ctor mat2x4<T: af_f32f16>(vec4<T>, vec4<T>) -> mat2x4<T>
+
+ctor mat3x2<T: af_f32f16>(T, T,
+ T, T,
+ T, T) -> mat3x2<T>
+ctor mat3x2<T: af_f32f16>(vec2<T>, vec2<T>, vec2<T>) -> mat3x2<T>
+
+ctor mat3x3<T: af_f32f16>(T, T, T,
+ T, T, T,
+ T, T, T) -> mat3x3<T>
+ctor mat3x3<T: af_f32f16>(vec3<T>, vec3<T>, vec3<T>) -> mat3x3<T>
+
+ctor mat3x4<T: af_f32f16>(T, T, T, T,
+ T, T, T, T,
+ T, T, T, T) -> mat3x4<T>
+ctor mat3x4<T: af_f32f16>(vec4<T>, vec4<T>, vec4<T>) -> mat3x4<T>
+
+ctor mat4x2<T: af_f32f16>(T, T,
+ T, T,
+ T, T,
+ T, T) -> mat4x2<T>
+ctor mat4x2<T: af_f32f16>(vec2<T>, vec2<T>, vec2<T>, vec2<T>) -> mat4x2<T>
+
+ctor mat4x3<T: af_f32f16>(T, T, T,
+ T, T, T,
+ T, T, T,
+ T, T, T) -> mat4x3<T>
+ctor mat4x3<T: af_f32f16>(vec3<T>, vec3<T>, vec3<T>, vec3<T>) -> mat4x3<T>
+
+ctor mat4x4<T: af_f32f16>(T, T, T, T,
+ T, T, T, T,
+ T, T, T, T,
+ T, T, T, T) -> mat4x4<T>
+ctor mat4x4<T: af_f32f16>(vec4<T>, vec4<T>, vec4<T>, vec4<T>) -> mat4x4<T>
////////////////////////////////////////////////////////////////////////////////
// Type conversions //
////////////////////////////////////////////////////////////////////////////////
conv f32<T: scalar_no_f32>(T) -> f32
+conv f16<T: scalar_no_f16>(T) -> f16
conv i32<T: scalar_no_i32>(T) -> i32
conv u32<T: scalar_no_u32>(T) -> u32
conv bool<T: scalar_no_bool>(T) -> bool
conv vec2<T: f32, U: scalar_no_f32>(vec2<U>) -> vec2<f32>
+conv vec2<T: f16, U: scalar_no_f16>(vec2<U>) -> vec2<f16>
conv vec2<T: i32, U: scalar_no_i32>(vec2<U>) -> vec2<i32>
conv vec2<T: u32, U: scalar_no_u32>(vec2<U>) -> vec2<u32>
conv vec2<T: bool, U: scalar_no_bool>(vec2<U>) -> vec2<bool>
conv vec3<T: f32, U: scalar_no_f32>(vec3<U>) -> vec3<f32>
+conv vec3<T: f16, U: scalar_no_f16>(vec3<U>) -> vec3<f16>
conv vec3<T: i32, U: scalar_no_i32>(vec3<U>) -> vec3<i32>
conv vec3<T: u32, U: scalar_no_u32>(vec3<U>) -> vec3<u32>
conv vec3<T: bool, U: scalar_no_bool>(vec3<U>) -> vec3<bool>
conv vec4<T: f32, U: scalar_no_f32>(vec4<U>) -> vec4<f32>
+conv vec4<T: f16, U: scalar_no_f16>(vec4<U>) -> vec4<f16>
conv vec4<T: i32, U: scalar_no_i32>(vec4<U>) -> vec4<i32>
conv vec4<T: u32, U: scalar_no_u32>(vec4<U>) -> vec4<u32>
conv vec4<T: bool, U: scalar_no_bool>(vec4<U>) -> vec4<bool>
+conv mat2x2<T: f16>(mat2x2<f32>) -> mat2x2<f16>
+conv mat2x2<T: f32>(mat2x2<f16>) -> mat2x2<f32>
+conv mat2x3<T: f16>(mat2x3<f32>) -> mat2x3<f16>
+conv mat2x3<T: f32>(mat2x3<f16>) -> mat2x3<f32>
+conv mat2x4<T: f16>(mat2x4<f32>) -> mat2x4<f16>
+conv mat2x4<T: f32>(mat2x4<f16>) -> mat2x4<f32>
+conv mat3x2<T: f16>(mat3x2<f32>) -> mat3x2<f16>
+conv mat3x2<T: f32>(mat3x2<f16>) -> mat3x2<f32>
+conv mat3x3<T: f16>(mat3x3<f32>) -> mat3x3<f16>
+conv mat3x3<T: f32>(mat3x3<f16>) -> mat3x3<f32>
+conv mat3x4<T: f16>(mat3x4<f32>) -> mat3x4<f16>
+conv mat3x4<T: f32>(mat3x4<f16>) -> mat3x4<f32>
+conv mat4x2<T: f16>(mat4x2<f32>) -> mat4x2<f16>
+conv mat4x2<T: f32>(mat4x2<f16>) -> mat4x2<f32>
+conv mat4x3<T: f16>(mat4x3<f32>) -> mat4x3<f16>
+conv mat4x3<T: f32>(mat4x3<f16>) -> mat4x3<f32>
+conv mat4x4<T: f16>(mat4x4<f32>) -> mat4x4<f16>
+conv mat4x4<T: f32>(mat4x4<f16>) -> mat4x4<f32>
+
////////////////////////////////////////////////////////////////////////////////
// Operators //
// //
diff --git a/src/tint/number.h b/src/tint/number.h
index 7f0c2f1..e130019 100644
--- a/src/tint/number.h
+++ b/src/tint/number.h
@@ -16,6 +16,7 @@
#define SRC_TINT_NUMBER_H_
#include <stdint.h>
+#include <cmath>
#include <functional>
#include <limits>
#include <optional>
@@ -135,61 +136,6 @@
return out << num.value;
}
-/// Equality operator.
-/// @param a the LHS number
-/// @param b the RHS number
-/// @returns true if the numbers `a` and `b` are exactly equal.
-template <typename A, typename B>
-bool operator==(Number<A> a, Number<B> b) {
- using T = decltype(a.value + b.value);
- return std::equal_to<T>()(static_cast<T>(a.value), static_cast<T>(b.value));
-}
-
-/// Inequality operator.
-/// @param a the LHS number
-/// @param b the RHS number
-/// @returns true if the numbers `a` and `b` are exactly unequal.
-template <typename A, typename B>
-bool operator!=(Number<A> a, Number<B> b) {
- return !(a == b);
-}
-
-/// Equality operator.
-/// @param a the LHS number
-/// @param b the RHS number
-/// @returns true if the numbers `a` and `b` are exactly equal.
-template <typename A, typename B>
-std::enable_if_t<IsNumeric<B>, bool> operator==(Number<A> a, B b) {
- return a == Number<B>(b);
-}
-
-/// Inequality operator.
-/// @param a the LHS number
-/// @param b the RHS number
-/// @returns true if the numbers `a` and `b` are exactly unequal.
-template <typename A, typename B>
-std::enable_if_t<IsNumeric<B>, bool> operator!=(Number<A> a, B b) {
- return !(a == b);
-}
-
-/// Equality operator.
-/// @param a the LHS number
-/// @param b the RHS number
-/// @returns true if the numbers `a` and `b` are exactly equal.
-template <typename A, typename B>
-std::enable_if_t<IsNumeric<A>, bool> operator==(A a, Number<B> b) {
- return Number<A>(a) == b;
-}
-
-/// Inequality operator.
-/// @param a the LHS number
-/// @param b the RHS number
-/// @returns true if the numbers `a` and `b` are exactly unequal.
-template <typename A, typename B>
-std::enable_if_t<IsNumeric<A>, bool> operator!=(A a, Number<B> b) {
- return !(a == b);
-}
-
/// The partial specification of Number for f16 type, storing the f16 value as float,
/// and enforcing proper explicit casting.
template <>
@@ -282,7 +228,9 @@
/// @returns the resulting value of the conversion, or a failure reason.
template <typename TO, typename FROM>
utils::Result<TO, ConversionFailure> CheckedConvert(Number<FROM> num) {
- using T = decltype(UnwrapNumber<TO>() + num.value);
+ // Use the highest-precision integer or floating-point type to perform the comparisons.
+ using T = std::conditional_t<IsFloatingPoint<UnwrapNumber<TO>> || IsFloatingPoint<FROM>,
+ AFloat::type, AInt::type>;
const auto value = static_cast<T>(num.value);
if (value > static_cast<T>(TO::kHighest)) {
return ConversionFailure::kExceedsPositiveLimit;
@@ -293,6 +241,70 @@
return TO(value); // Success
}
+/// Equality operator.
+/// @param a the LHS number
+/// @param b the RHS number
+/// @returns true if the numbers `a` and `b` are exactly equal. Also considers sign bit.
+template <typename A, typename B>
+bool operator==(Number<A> a, Number<B> b) {
+ // Use the highest-precision integer or floating-point type to perform the comparisons.
+ using T =
+ std::conditional_t<IsFloatingPoint<A> || IsFloatingPoint<B>, AFloat::type, AInt::type>;
+ auto va = static_cast<T>(a.value);
+ auto vb = static_cast<T>(b.value);
+ if constexpr (IsFloatingPoint<T>) {
+ if (std::signbit(va) != std::signbit(vb)) {
+ return false;
+ }
+ }
+ return std::equal_to<T>()(va, vb);
+}
+
+/// Inequality operator.
+/// @param a the LHS number
+/// @param b the RHS number
+/// @returns true if the numbers `a` and `b` are exactly unequal. Also considers sign bit.
+template <typename A, typename B>
+bool operator!=(Number<A> a, Number<B> b) {
+ return !(a == b);
+}
+
+/// Equality operator.
+/// @param a the LHS number
+/// @param b the RHS number
+/// @returns true if the numbers `a` and `b` are exactly equal.
+template <typename A, typename B>
+std::enable_if_t<IsNumeric<B>, bool> operator==(Number<A> a, B b) {
+ return a == Number<B>(b);
+}
+
+/// Inequality operator.
+/// @param a the LHS number
+/// @param b the RHS number
+/// @returns true if the numbers `a` and `b` are exactly unequal.
+template <typename A, typename B>
+std::enable_if_t<IsNumeric<B>, bool> operator!=(Number<A> a, B b) {
+ return !(a == b);
+}
+
+/// Equality operator.
+/// @param a the LHS number
+/// @param b the RHS number
+/// @returns true if the numbers `a` and `b` are exactly equal.
+template <typename A, typename B>
+std::enable_if_t<IsNumeric<A>, bool> operator==(A a, Number<B> b) {
+ return Number<A>(a) == b;
+}
+
+/// Inequality operator.
+/// @param a the LHS number
+/// @param b the RHS number
+/// @returns true if the numbers `a` and `b` are exactly unequal.
+template <typename A, typename B>
+std::enable_if_t<IsNumeric<A>, bool> operator!=(A a, Number<B> b) {
+ return !(a == b);
+}
+
/// Define 'TINT_HAS_OVERFLOW_BUILTINS' if the compiler provide overflow checking builtins.
/// If the compiler does not support these builtins, then these are emulated with algorithms
/// described in:
diff --git a/src/tint/number_test.cc b/src/tint/number_test.cc
index 52ba4ae..81acc04 100644
--- a/src/tint/number_test.cc
+++ b/src/tint/number_test.cc
@@ -65,6 +65,79 @@
// warning.
TINT_BEGIN_DISABLE_WARNING(CONSTANT_OVERFLOW);
+TEST(NumberTest, Equality) {
+ EXPECT_TRUE(0_a == 0_a);
+ EXPECT_TRUE(10_a == 10_a);
+ EXPECT_TRUE(-10_a == -10_a);
+
+ EXPECT_TRUE(0_i == 0_i);
+ EXPECT_TRUE(10_i == 10_i);
+ EXPECT_TRUE(-10_i == -10_i);
+
+ EXPECT_TRUE(0_u == 0_u);
+ EXPECT_TRUE(10_u == 10_u);
+
+ EXPECT_TRUE(0._a == 0._a);
+ EXPECT_TRUE(-0._a == -0._a);
+ EXPECT_TRUE(10._a == 10._a);
+ EXPECT_TRUE(-10._a == -10._a);
+
+ EXPECT_TRUE(0_f == 0_f);
+ EXPECT_TRUE(-0_f == -0_f);
+ EXPECT_TRUE(10_f == 10_f);
+ EXPECT_TRUE(-10_f == -10_f);
+
+ EXPECT_TRUE(0_h == 0_h);
+ EXPECT_TRUE(-0_h == -0_h);
+ EXPECT_TRUE(10_h == 10_h);
+ EXPECT_TRUE(-10_h == -10_h);
+}
+
+TEST(NumberTest, Inequality) {
+ EXPECT_TRUE(0_a != 1_a);
+ EXPECT_TRUE(10_a != 11_a);
+ EXPECT_TRUE(11_a != 10_a);
+ EXPECT_TRUE(-10_a != -11_a);
+ EXPECT_TRUE(-11_a != -10_a);
+
+ EXPECT_TRUE(0_i != 1_i);
+ EXPECT_TRUE(1_i != 0_i);
+ EXPECT_TRUE(10_i != 11_i);
+ EXPECT_TRUE(11_i != 10_i);
+ EXPECT_TRUE(-10_i != -11_i);
+ EXPECT_TRUE(-11_i != -10_i);
+
+ EXPECT_TRUE(0_u != 1_u);
+ EXPECT_TRUE(1_u != 0_u);
+ EXPECT_TRUE(10_u != 11_u);
+ EXPECT_TRUE(11_u != 10_u);
+
+ EXPECT_TRUE(0._a != -0._a);
+ EXPECT_TRUE(-0._a != 0._a);
+ EXPECT_TRUE(10._a != 11._a);
+ EXPECT_TRUE(11._a != 10._a);
+ EXPECT_TRUE(-10._a != -11._a);
+ EXPECT_TRUE(-11._a != -10._a);
+
+ EXPECT_TRUE(0_f != -0_f);
+ EXPECT_TRUE(-0_f != 0_f);
+ EXPECT_TRUE(-0_f != -1_f);
+ EXPECT_TRUE(-1_f != -0_f);
+ EXPECT_TRUE(10_f != -10_f);
+ EXPECT_TRUE(-10_f != 10_f);
+ EXPECT_TRUE(10_f != 11_f);
+ EXPECT_TRUE(-10_f != -11_f);
+
+ EXPECT_TRUE(0_h != -0_h);
+ EXPECT_TRUE(-0_h != 0_h);
+ EXPECT_TRUE(-0_h != -1_h);
+ EXPECT_TRUE(-1_h != -0_h);
+ EXPECT_TRUE(10_h != -10_h);
+ EXPECT_TRUE(-10_h != 10_h);
+ EXPECT_TRUE(10_h != 11_h);
+ EXPECT_TRUE(-10_h != -11_h);
+}
+
TEST(NumberTest, CheckedConvertIdentity) {
EXPECT_EQ(CheckedConvert<AInt>(0_a), 0_a);
EXPECT_EQ(CheckedConvert<AFloat>(0_a), 0.0_a);
@@ -84,6 +157,7 @@
TEST(NumberTest, CheckedConvertLargestValue) {
EXPECT_EQ(CheckedConvert<i32>(AInt(kHighestI32)), i32(kHighestI32));
EXPECT_EQ(CheckedConvert<u32>(AInt(kHighestU32)), u32(kHighestU32));
+ EXPECT_EQ(CheckedConvert<u32>(i32(kHighestI32)), u32(kHighestI32));
EXPECT_EQ(CheckedConvert<f32>(AFloat(kHighestF32)), f32(kHighestF32));
EXPECT_EQ(CheckedConvert<f16>(AFloat(kHighestF16)), f16(kHighestF16));
}
@@ -105,6 +179,14 @@
TEST(NumberTest, CheckedConvertExceedsPositiveLimit) {
EXPECT_EQ(CheckedConvert<i32>(AInt(kHighestI32 + 1)), ConversionFailure::kExceedsPositiveLimit);
EXPECT_EQ(CheckedConvert<u32>(AInt(kHighestU32 + 1)), ConversionFailure::kExceedsPositiveLimit);
+ EXPECT_EQ(CheckedConvert<i32>(u32(kHighestU32)), ConversionFailure::kExceedsPositiveLimit);
+ EXPECT_EQ(CheckedConvert<i32>(u32(0x80000000)), ConversionFailure::kExceedsPositiveLimit);
+ EXPECT_EQ(CheckedConvert<u32>(f32(f32::kHighest)), ConversionFailure::kExceedsPositiveLimit);
+ EXPECT_EQ(CheckedConvert<i32>(f32(f32::kHighest)), ConversionFailure::kExceedsPositiveLimit);
+ EXPECT_EQ(CheckedConvert<u32>(AFloat(AFloat::kHighest)),
+ ConversionFailure::kExceedsPositiveLimit);
+ EXPECT_EQ(CheckedConvert<i32>(AFloat(AFloat::kHighest)),
+ ConversionFailure::kExceedsPositiveLimit);
EXPECT_EQ(CheckedConvert<f32>(AFloat(kHighestF32NextULP)),
ConversionFailure::kExceedsPositiveLimit);
EXPECT_EQ(CheckedConvert<f16>(AFloat(kHighestF16NextULP)),
@@ -114,6 +196,14 @@
TEST(NumberTest, CheckedConvertExceedsNegativeLimit) {
EXPECT_EQ(CheckedConvert<i32>(AInt(kLowestI32 - 1)), ConversionFailure::kExceedsNegativeLimit);
EXPECT_EQ(CheckedConvert<u32>(AInt(kLowestU32 - 1)), ConversionFailure::kExceedsNegativeLimit);
+ EXPECT_EQ(CheckedConvert<u32>(i32(-1)), ConversionFailure::kExceedsNegativeLimit);
+ EXPECT_EQ(CheckedConvert<u32>(i32(kLowestI32)), ConversionFailure::kExceedsNegativeLimit);
+ EXPECT_EQ(CheckedConvert<u32>(f32(f32::kLowest)), ConversionFailure::kExceedsNegativeLimit);
+ EXPECT_EQ(CheckedConvert<i32>(f32(f32::kLowest)), ConversionFailure::kExceedsNegativeLimit);
+ EXPECT_EQ(CheckedConvert<u32>(AFloat(AFloat::kLowest)),
+ ConversionFailure::kExceedsNegativeLimit);
+ EXPECT_EQ(CheckedConvert<i32>(AFloat(AFloat::kLowest)),
+ ConversionFailure::kExceedsNegativeLimit);
EXPECT_EQ(CheckedConvert<f32>(AFloat(kLowestF32NextULP)),
ConversionFailure::kExceedsNegativeLimit);
EXPECT_EQ(CheckedConvert<f16>(AFloat(kLowestF16NextULP)),
@@ -194,7 +284,7 @@
EXPECT_EQ(f16(lowestNegativeSubnormalF16PlusULP), -0x0.ff8p-14);
EXPECT_EQ(f16(highestNegativeSubnormalF16MinusULP), highestNegativeSubnormalF16);
EXPECT_EQ(f16(highestNegativeSubnormalF16), highestNegativeSubnormalF16);
- EXPECT_EQ(f16(highestNegativeSubnormalF16PlusULP), 0.0);
+ EXPECT_EQ(f16(highestNegativeSubnormalF16PlusULP), -0.0);
// Test the mantissa discarding.
EXPECT_EQ(f16(-0x0.064p-14), -0x0.064p-14);
EXPECT_EQ(f16(-0x0.067fecp-14), -0x0.064p-14);
diff --git a/src/tint/program.cc b/src/tint/program.cc
index 6722a09..1afbd46 100644
--- a/src/tint/program.cc
+++ b/src/tint/program.cc
@@ -38,6 +38,7 @@
types_(std::move(program.types_)),
ast_nodes_(std::move(program.ast_nodes_)),
sem_nodes_(std::move(program.sem_nodes_)),
+ constant_nodes_(std::move(program.constant_nodes_)),
ast_(std::move(program.ast_)),
sem_(std::move(program.sem_)),
symbols_(std::move(program.symbols_)),
@@ -62,6 +63,7 @@
types_ = std::move(builder.Types());
ast_nodes_ = std::move(builder.ASTNodes());
sem_nodes_ = std::move(builder.SemNodes());
+ constant_nodes_ = std::move(builder.ConstantNodes());
ast_ = &builder.AST(); // ast::Module is actually a heap allocation.
sem_ = std::move(builder.Sem());
symbols_ = std::move(builder.Symbols());
@@ -86,6 +88,7 @@
types_ = std::move(program.types_);
ast_nodes_ = std::move(program.ast_nodes_);
sem_nodes_ = std::move(program.sem_nodes_);
+ constant_nodes_ = std::move(program.constant_nodes_);
ast_ = std::move(program.ast_);
sem_ = std::move(program.sem_);
symbols_ = std::move(program.symbols_);
diff --git a/src/tint/program.h b/src/tint/program.h
index 3230e7e..5fd31dd 100644
--- a/src/tint/program.h
+++ b/src/tint/program.h
@@ -20,6 +20,7 @@
#include "src/tint/ast/function.h"
#include "src/tint/program_id.h"
+#include "src/tint/sem/constant.h"
#include "src/tint/sem/info.h"
#include "src/tint/sem/type_manager.h"
#include "src/tint/symbol_table.h"
@@ -43,6 +44,9 @@
/// SemNodeAllocator is an alias to BlockAllocator<sem::Node>
using SemNodeAllocator = utils::BlockAllocator<sem::Node>;
+ /// ConstantAllocator is an alias to BlockAllocator<sem::Constant>
+ using ConstantAllocator = utils::BlockAllocator<sem::Constant>;
+
/// Constructor
Program();
@@ -160,6 +164,7 @@
sem::Manager types_;
ASTNodeAllocator ast_nodes_;
SemNodeAllocator sem_nodes_;
+ ConstantAllocator constant_nodes_;
ast::Module* ast_ = nullptr;
sem::Info sem_;
SymbolTable symbols_{id_};
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index 5492867..e9b0a80 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -33,6 +33,7 @@
#include "src/tint/ast/call_statement.h"
#include "src/tint/ast/case_statement.h"
#include "src/tint/ast/compound_assignment_statement.h"
+#include "src/tint/ast/const.h"
#include "src/tint/ast/continue_statement.h"
#include "src/tint/ast/depth_multisampled_texture.h"
#include "src/tint/ast/depth_texture.h"
@@ -87,6 +88,7 @@
#include "src/tint/program_id.h"
#include "src/tint/sem/array.h"
#include "src/tint/sem/bool.h"
+#include "src/tint/sem/constant.h"
#include "src/tint/sem/depth_texture.h"
#include "src/tint/sem/external_texture.h"
#include "src/tint/sem/f16.h"
@@ -128,7 +130,7 @@
traits::EnableIfIsNotType<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>, Source>;
/// VarOptionals is a helper for accepting a number of optional, extra
- /// arguments for Var() and Global().
+ /// arguments for Var() and GlobalVar().
struct VarOptionals {
template <typename... ARGS>
explicit VarOptionals(ARGS&&... args) {
@@ -162,6 +164,9 @@
/// SemNodeAllocator is an alias to BlockAllocator<sem::Node>
using SemNodeAllocator = utils::BlockAllocator<sem::Node>;
+ /// ConstantAllocator is an alias to BlockAllocator<sem::Constant>
+ using ConstantAllocator = utils::BlockAllocator<sem::Constant>;
+
/// Constructor
ProgramBuilder();
@@ -228,6 +233,12 @@
return sem_nodes_;
}
+ /// @returns a reference to the program's semantic constant storage
+ ConstantAllocator& ConstantNodes() {
+ AssertNotMoved();
+ return constant_nodes_;
+ }
+
/// @returns a reference to the program's AST root Module
ast::Module& AST() {
AssertNotMoved();
@@ -331,9 +342,8 @@
}
/// Creates a new sem::Node owned by the ProgramBuilder.
- /// When the ProgramBuilder is destructed, the sem::Node will also be
- /// destructed.
- /// @param args the arguments to pass to the type constructor
+ /// When the ProgramBuilder is destructed, the sem::Node will also be destructed.
+ /// @param args the arguments to pass to the constructor
/// @returns the node pointer
template <typename T, typename... ARGS>
traits::EnableIf<traits::IsTypeOrDerived<T, sem::Node> &&
@@ -344,6 +354,16 @@
return sem_nodes_.Create<T>(std::forward<ARGS>(args)...);
}
+ /// Creates a new sem::Constant owned by the ProgramBuilder.
+ /// When the ProgramBuilder is destructed, the sem::Node will also be destructed.
+ /// @param args the arguments to pass to the constructor
+ /// @returns the node pointer
+ template <typename T, typename... ARGS>
+ traits::EnableIf<traits::IsTypeOrDerived<T, sem::Constant>, T>* create(ARGS&&... args) {
+ AssertNotMoved();
+ return constant_nodes_.Create<T>(std::forward<ARGS>(args)...);
+ }
+
/// Creates a new sem::Type owned by the ProgramBuilder.
/// When the ProgramBuilder is destructed, owned ProgramBuilder and the
/// returned`Type` will also be destructed.
@@ -1367,6 +1387,35 @@
/// @param type the variable type
/// @param constructor constructor expression
/// @param attributes optional variable attributes
+ /// @returns an `ast::Const` with the given name and type
+ template <typename NAME>
+ const ast::Const* Const(NAME&& name,
+ const ast::Type* type,
+ const ast::Expression* constructor,
+ ast::AttributeList attributes = {}) {
+ return create<ast::Const>(Sym(std::forward<NAME>(name)), type, constructor, attributes);
+ }
+
+ /// @param source the variable source
+ /// @param name the variable name
+ /// @param type the variable type
+ /// @param constructor constructor expression
+ /// @param attributes optional variable attributes
+ /// @returns an `ast::Const` with the given name and type
+ template <typename NAME>
+ const ast::Const* Const(const Source& source,
+ NAME&& name,
+ const ast::Type* type,
+ const ast::Expression* constructor,
+ ast::AttributeList attributes = {}) {
+ return create<ast::Const>(source, Sym(std::forward<NAME>(name)), type, constructor,
+ attributes);
+ }
+
+ /// @param name the variable name
+ /// @param type the variable type
+ /// @param constructor constructor expression
+ /// @param attributes optional variable attributes
/// @returns an `ast::Let` with the given name and type
template <typename NAME>
const ast::Let* Let(NAME&& name,
@@ -1429,7 +1478,7 @@
/// @returns a new `ast::Var`, which is automatically registered as a global variable with the
/// ast::Module.
template <typename NAME, typename... OPTIONAL, typename = DisableIfSource<NAME>>
- const ast::Var* Global(NAME&& name, const ast::Type* type, OPTIONAL&&... optional) {
+ const ast::Var* GlobalVar(NAME&& name, const ast::Type* type, OPTIONAL&&... optional) {
auto* var = Var(std::forward<NAME>(name), type, std::forward<OPTIONAL>(optional)...);
AST().AddGlobalVariable(var);
return var;
@@ -1449,10 +1498,10 @@
/// @returns a new `ast::Var`, which is automatically registered as a global variable with the
/// ast::Module.
template <typename NAME, typename... OPTIONAL>
- const ast::Var* Global(const Source& source,
- NAME&& name,
- const ast::Type* type,
- OPTIONAL&&... optional) {
+ const ast::Var* GlobalVar(const Source& source,
+ NAME&& name,
+ const ast::Type* type,
+ OPTIONAL&&... optional) {
auto* var =
Var(source, std::forward<NAME>(name), type, std::forward<OPTIONAL>(optional)...);
AST().AddGlobalVariable(var);
@@ -1463,14 +1512,14 @@
/// @param type the variable type
/// @param constructor constructor expression
/// @param attributes optional variable attributes
- /// @returns an `ast::Let` constructed by calling Let() with the arguments of `args`, which is
- /// automatically registered as a global variable with the ast::Module.
+ /// @returns an `ast::Const` constructed by calling Const() with the arguments of `args`, which
+ /// is automatically registered as a global variable with the ast::Module.
template <typename NAME>
- const ast::Let* GlobalConst(NAME&& name,
- const ast::Type* type,
- const ast::Expression* constructor,
- ast::AttributeList attributes = {}) {
- auto* var = Let(std::forward<NAME>(name), type, constructor, std::move(attributes));
+ const ast::Const* GlobalConst(NAME&& name,
+ const ast::Type* type,
+ const ast::Expression* constructor,
+ ast::AttributeList attributes = {}) {
+ auto* var = Const(std::forward<NAME>(name), type, constructor, std::move(attributes));
AST().AddGlobalVariable(var);
return var;
}
@@ -1480,16 +1529,17 @@
/// @param type the variable type
/// @param constructor constructor expression
/// @param attributes optional variable attributes
- /// @returns a const `ast::Let` constructed by calling Var() with the
+ /// @returns a const `ast::Const` constructed by calling Var() with the
/// arguments of `args`, which is automatically registered as a global
/// variable with the ast::Module.
template <typename NAME>
- const ast::Let* GlobalConst(const Source& source,
- NAME&& name,
- const ast::Type* type,
- const ast::Expression* constructor,
- ast::AttributeList attributes = {}) {
- auto* var = Let(source, std::forward<NAME>(name), type, constructor, std::move(attributes));
+ const ast::Const* GlobalConst(const Source& source,
+ NAME&& name,
+ const ast::Type* type,
+ const ast::Expression* constructor,
+ ast::AttributeList attributes = {}) {
+ auto* var =
+ Const(source, std::forward<NAME>(name), type, constructor, std::move(attributes));
AST().AddGlobalVariable(var);
return var;
}
@@ -2716,6 +2766,7 @@
sem::Manager types_;
ASTNodeAllocator ast_nodes_;
SemNodeAllocator sem_nodes_;
+ ConstantAllocator constant_nodes_;
ast::Module* ast_;
sem::Info sem_;
SymbolTable symbols_{id_};
diff --git a/src/tint/program_test.cc b/src/tint/program_test.cc
index 3bdf11a..ae6aabe 100644
--- a/src/tint/program_test.cc
+++ b/src/tint/program_test.cc
@@ -46,7 +46,7 @@
}
TEST_F(ProgramTest, Assert_GlobalVariable) {
- Global("var", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
Program program(std::move(*this));
EXPECT_TRUE(program.IsValid());
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index 2a5169b..2bcae95 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -36,6 +36,7 @@
#include "src/tint/sem/builtin_type.h"
#include "src/tint/sem/depth_texture.h"
#include "src/tint/sem/sampled_texture.h"
+#include "src/tint/transform/spirv_atomic.h"
// Terms:
// CFG: the control flow graph of the function, where basic blocks are the
@@ -501,6 +502,38 @@
}
// @param opcode a SPIR-V opcode
+// @returns true if the given instruction is an atomic operation.
+bool IsAtomicOp(SpvOp opcode) {
+ switch (opcode) {
+ case SpvOpAtomicLoad:
+ case SpvOpAtomicStore:
+ case SpvOpAtomicExchange:
+ case SpvOpAtomicCompareExchange:
+ case SpvOpAtomicCompareExchangeWeak:
+ case SpvOpAtomicIIncrement:
+ case SpvOpAtomicIDecrement:
+ case SpvOpAtomicIAdd:
+ case SpvOpAtomicISub:
+ case SpvOpAtomicSMin:
+ case SpvOpAtomicUMin:
+ case SpvOpAtomicSMax:
+ case SpvOpAtomicUMax:
+ case SpvOpAtomicAnd:
+ case SpvOpAtomicOr:
+ case SpvOpAtomicXor:
+ case SpvOpAtomicFlagTestAndSet:
+ case SpvOpAtomicFlagClear:
+ case SpvOpAtomicFMinEXT:
+ case SpvOpAtomicFMaxEXT:
+ case SpvOpAtomicFAddEXT:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+// @param opcode a SPIR-V opcode
// @returns true if the given instruction is an image sampling, gather,
// or gather-compare operation.
bool IsImageSamplingOrGatherOrDrefGather(SpvOp opcode) {
@@ -991,11 +1024,13 @@
[&](const Struct* struct_type) -> bool {
const auto& members = struct_type->members;
index_prefix.push_back(0);
- for (int i = 0; i < static_cast<int>(members.size()); ++i) {
- index_prefix.back() = i;
+ for (size_t i = 0; i < members.size(); ++i) {
+ index_prefix.back() = static_cast<int>(i);
ast::AttributeList member_attrs(*attrs);
if (!parser_impl_.ConvertPipelineDecorations(
- struct_type, parser_impl_.GetMemberPipelineDecorations(*struct_type, i),
+ struct_type,
+ parser_impl_.GetMemberPipelineDecorations(*struct_type,
+ static_cast<int>(i)),
&member_attrs)) {
return false;
}
@@ -1045,7 +1080,7 @@
store_dest = builder_.MemberAccessor(
store_dest,
builder_.Expr(parser_impl_.GetMemberName(*struct_type, index)));
- current_type = struct_type->members[index];
+ current_type = struct_type->members[static_cast<size_t>(index)];
});
}
@@ -1141,8 +1176,9 @@
&member_attrs)) {
return false;
}
- if (!EmitPipelineOutput(var_name, var_type, &member_attrs, index_prefix, members[i],
- forced_member_type, return_members, return_exprs)) {
+ if (!EmitPipelineOutput(var_name, var_type, &member_attrs, index_prefix,
+ members[static_cast<size_t>(i)], forced_member_type,
+ return_members, return_exprs)) {
return false;
}
// Copy the location as updated by nested expansion of the member.
@@ -1190,7 +1226,7 @@
load_source = builder_.MemberAccessor(
load_source,
builder_.Expr(parser_impl_.GetMemberName(*struct_type, index)));
- current_type = struct_type->members[index];
+ current_type = struct_type->members[static_cast<size_t>(index)];
});
}
@@ -1792,7 +1828,7 @@
// The current block is a header.
const auto header = block_id;
const auto* header_info = block_info;
- const auto depth = 1 + top->depth;
+ const auto depth = static_cast<size_t>(1 + top->depth);
const auto ct = header_info->continue_for_header;
if (ct != 0) {
// The current block is a loop header.
@@ -3487,6 +3523,10 @@
return EmitImageAccess(inst);
}
+ if (IsAtomicOp(inst.opcode())) {
+ return EmitAtomicOp(inst);
+ }
+
switch (inst.opcode()) {
case SpvOpNop:
return true;
@@ -4273,7 +4313,7 @@
// This is structurally similar to creating an access chain, but
// the SPIR-V instruction has literal indices instead of IDs for indices.
- auto composite_index = 0;
+ auto composite_index = 0u;
auto first_index_position = 1;
TypedExpression current_expr(MakeOperand(inst, composite_index));
if (!current_expr) {
@@ -4317,13 +4357,14 @@
// hierarchy, maintaining |current_type_id| as the SPIR-V ID of the type of
// the object pointed to after processing the previous indices.
const auto num_in_operands = inst.NumInOperands();
- for (uint32_t index = index_start; index < num_in_operands; ++index) {
+ for (uint32_t index = static_cast<uint32_t>(index_start); index < num_in_operands; ++index) {
const uint32_t index_val = inst.GetSingleWordInOperand(index);
const auto* current_type_inst = def_use_mgr_->GetDef(current_type_id);
if (!current_type_inst) {
Fail() << "composite type %" << current_type_id << " is invalid after following "
- << (index - index_start) << " indices: " << inst.PrettyPrint();
+ << (index - static_cast<uint32_t>(index_start))
+ << " indices: " << inst.PrettyPrint();
return {};
}
const char* operation_name = nullptr;
@@ -4613,7 +4654,7 @@
// but only if they are defined in this function as well.
auto require_named_const_def = [&](const spvtools::opt::Instruction& inst,
int in_operand_index) {
- const auto id = inst.GetSingleWordInOperand(in_operand_index);
+ const auto id = inst.GetSingleWordInOperand(static_cast<uint32_t>(in_operand_index));
auto* const operand_def = GetDefInfo(id);
if (operand_def) {
operand_def->requires_named_const_def = true;
@@ -4881,7 +4922,7 @@
bool FunctionEmitter::EmitControlBarrier(const spvtools::opt::Instruction& inst) {
uint32_t operands[3];
- for (int i = 0; i < 3; i++) {
+ for (uint32_t i = 0; i < 3; i++) {
auto id = inst.GetSingleWordInOperand(i);
if (auto* constant = constant_mgr_->FindDeclaredConstant(id)) {
operands[i] = constant->GetU32();
@@ -4899,7 +4940,7 @@
<< "expected Workgroup (2), got: " << execution;
}
if (semantics & SpvMemorySemanticsAcquireReleaseMask) {
- semantics &= ~SpvMemorySemanticsAcquireReleaseMask;
+ semantics &= ~static_cast<uint32_t>(SpvMemorySemanticsAcquireReleaseMask);
} else {
return Fail() << "control barrier semantics requires acquire and release";
}
@@ -4908,14 +4949,14 @@
return Fail() << "workgroupBarrier requires workgroup memory scope";
}
AddStatement(create<ast::CallStatement>(builder_.Call("workgroupBarrier")));
- semantics &= ~SpvMemorySemanticsWorkgroupMemoryMask;
+ semantics &= ~static_cast<uint32_t>(SpvMemorySemanticsWorkgroupMemoryMask);
}
if (semantics & SpvMemorySemanticsUniformMemoryMask) {
if (memory != SpvScopeDevice) {
return Fail() << "storageBarrier requires device memory scope";
}
AddStatement(create<ast::CallStatement>(builder_.Call("storageBarrier")));
- semantics &= ~SpvMemorySemanticsUniformMemoryMask;
+ semantics &= ~static_cast<uint32_t>(SpvMemorySemanticsUniformMemoryMask);
}
if (semantics) {
return Fail() << "unsupported control barrier semantics: " << semantics;
@@ -5417,6 +5458,115 @@
return Fail() << "unhandled image query: " << inst.PrettyPrint();
}
+bool FunctionEmitter::EmitAtomicOp(const spvtools::opt::Instruction& inst) {
+ auto emit_atomic = [&](sem::BuiltinType builtin, std::initializer_list<TypedExpression> args) {
+ // Split args into params and expressions
+ ast::ParameterList params;
+ params.reserve(args.size());
+ ast::ExpressionList exprs;
+ exprs.reserve(args.size());
+ size_t i = 0;
+ for (auto& a : args) {
+ params.emplace_back(builder_.Param("p" + std::to_string(i++), a.type->Build(builder_)));
+ exprs.emplace_back(a.expr);
+ }
+
+ // Function return type
+ const ast::Type* ret_type = nullptr;
+ if (inst.type_id() != 0) {
+ ret_type = parser_impl_.ConvertType(inst.type_id())->Build(builder_);
+ } else {
+ ret_type = builder_.ty.void_();
+ }
+
+ // Emit stub, will be removed by transform::SpirvAtomic
+ auto sym = builder_.Symbols().New(std::string("stub_") + sem::str(builtin));
+ auto* stub_deco =
+ builder_.ASTNodes().Create<transform::SpirvAtomic::Stub>(builder_.ID(), builtin);
+ auto* stub =
+ create<ast::Function>(Source{}, sym, std::move(params), ret_type,
+ /* body */ nullptr,
+ ast::AttributeList{
+ stub_deco,
+ builder_.Disable(ast::DisabledValidation::kFunctionHasNoBody),
+ },
+ ast::AttributeList{});
+ builder_.AST().AddFunction(stub);
+
+ // Emit call to stub, will be replaced with call to atomic builtin by transform::SpirvAtomic
+ auto* call = builder_.Call(Source{}, sym, exprs);
+ if (inst.type_id() != 0) {
+ auto* result_type = parser_impl_.ConvertType(inst.type_id());
+ TypedExpression expr{result_type, call};
+ return EmitConstDefOrWriteToHoistedVar(inst, expr);
+ }
+ AddStatement(create<ast::CallStatement>(call));
+
+ return true;
+ };
+
+ auto oper = [&](uint32_t index) -> TypedExpression { //
+ return MakeOperand(inst, index);
+ };
+
+ auto lit = [&](int v) -> TypedExpression {
+ auto* result_type = parser_impl_.ConvertType(inst.type_id());
+ if (result_type->Is<I32>()) {
+ return TypedExpression(result_type, builder_.Expr(i32(v)));
+ } else if (result_type->Is<U32>()) {
+ return TypedExpression(result_type, builder_.Expr(u32(v)));
+ }
+ return {};
+ };
+
+ switch (inst.opcode()) {
+ case SpvOpAtomicLoad:
+ return emit_atomic(sem::BuiltinType::kAtomicLoad, {oper(/*ptr*/ 0)});
+ case SpvOpAtomicStore:
+ return emit_atomic(sem::BuiltinType::kAtomicStore,
+ {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicExchange:
+ return emit_atomic(sem::BuiltinType::kAtomicExchange,
+ {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicCompareExchange:
+ case SpvOpAtomicCompareExchangeWeak:
+ return emit_atomic(sem::BuiltinType::kAtomicCompareExchangeWeak,
+ {oper(/*ptr*/ 0), /*value*/ oper(5), /*comparator*/ oper(4)});
+ case SpvOpAtomicIIncrement:
+ return emit_atomic(sem::BuiltinType::kAtomicAdd, {oper(/*ptr*/ 0), lit(1)});
+ case SpvOpAtomicIDecrement:
+ return emit_atomic(sem::BuiltinType::kAtomicSub, {oper(/*ptr*/ 0), lit(1)});
+ case SpvOpAtomicIAdd:
+ return emit_atomic(sem::BuiltinType::kAtomicAdd, {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicISub:
+ return emit_atomic(sem::BuiltinType::kAtomicSub, {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicSMin:
+ return emit_atomic(sem::BuiltinType::kAtomicMin, {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicUMin:
+ return emit_atomic(sem::BuiltinType::kAtomicMin, {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicSMax:
+ return emit_atomic(sem::BuiltinType::kAtomicMax, {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicUMax:
+ return emit_atomic(sem::BuiltinType::kAtomicMax, {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicAnd:
+ return emit_atomic(sem::BuiltinType::kAtomicAnd, {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicOr:
+ return emit_atomic(sem::BuiltinType::kAtomicOr, {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicXor:
+ return emit_atomic(sem::BuiltinType::kAtomicXor, {oper(/*ptr*/ 0), oper(/*value*/ 3)});
+ case SpvOpAtomicFlagTestAndSet:
+ case SpvOpAtomicFlagClear:
+ case SpvOpAtomicFMinEXT:
+ case SpvOpAtomicFMaxEXT:
+ case SpvOpAtomicFAddEXT:
+ return Fail() << "unsupported atomic op: " << inst.PrettyPrint();
+
+ default:
+ break;
+ }
+ return Fail() << "unhandled atomic op: " << inst.PrettyPrint();
+}
+
ast::ExpressionList FunctionEmitter::MakeCoordinateOperandsForImageAccess(
const spvtools::opt::Instruction& inst) {
if (!parser_impl_.success()) {
@@ -5454,7 +5604,7 @@
}
ast::TextureDimension dim = texture_type->dims;
// Number of regular coordinates.
- uint32_t num_axes = ast::NumCoordinateAxes(dim);
+ uint32_t num_axes = static_cast<uint32_t>(ast::NumCoordinateAxes(dim));
bool is_arrayed = ast::IsTextureArray(dim);
if ((num_axes == 0) || (num_axes > 3)) {
Fail() << "unsupported image dimensionality for " << texture_type->TypeInfo().name
diff --git a/src/tint/reader/spirv/function.h b/src/tint/reader/spirv/function.h
index b1c3f57..ae9ef31 100644
--- a/src/tint/reader/spirv/function.h
+++ b/src/tint/reader/spirv/function.h
@@ -1060,7 +1060,7 @@
/// Emits a texture builtin function call for a SPIR-V instruction that
/// accesses an image or sampled image.
/// @param inst the SPIR-V instruction
- /// @returns an expression
+ /// @returns true on success, false on error
bool EmitImageAccess(const spvtools::opt::Instruction& inst);
/// Emits statements to implement a SPIR-V image query.
@@ -1068,6 +1068,11 @@
/// @returns an expression
bool EmitImageQuery(const spvtools::opt::Instruction& inst);
+ /// Emits statements to implement a SPIR-V atomic op.
+ /// @param inst the SPIR-V instruction
+ /// @returns true on success, false on error
+ bool EmitAtomicOp(const spvtools::opt::Instruction& inst);
+
/// Converts the given texel to match the type required for the storage
/// texture with the given type. In WGSL the texel value is always provided
/// as a 4-element vector, but the component type is determined by the
diff --git a/src/tint/reader/spirv/parser.cc b/src/tint/reader/spirv/parser.cc
index f430d94..ac43b9e 100644
--- a/src/tint/reader/spirv/parser.cc
+++ b/src/tint/reader/spirv/parser.cc
@@ -22,6 +22,7 @@
#include "src/tint/transform/manager.h"
#include "src/tint/transform/remove_unreachable_statements.h"
#include "src/tint/transform/simplify_pointers.h"
+#include "src/tint/transform/spirv_atomic.h"
#include "src/tint/transform/unshadow.h"
namespace tint::reader::spirv {
@@ -55,6 +56,7 @@
manager.Add<transform::DecomposeStridedMatrix>();
manager.Add<transform::DecomposeStridedArray>();
manager.Add<transform::RemoveUnreachableStatements>();
+ manager.Add<transform::SpirvAtomic>();
return manager.Run(&program).program;
}
diff --git a/src/tint/reader/spirv/parser_impl.cc b/src/tint/reader/spirv/parser_impl.cc
index 1ebf0b9..b34f66b 100644
--- a/src/tint/reader/spirv/parser_impl.cc
+++ b/src/tint/reader/spirv/parser_impl.cc
@@ -816,7 +816,7 @@
/// Returns false and emits a diagnostic on error.
auto set_param = [this, composite_def](uint32_t* id_ptr, uint32_t* value_ptr,
int index) -> bool {
- const auto id = composite_def->GetSingleWordInOperand(index);
+ const auto id = composite_def->GetSingleWordInOperand(static_cast<uint32_t>(index));
const auto* def = def_use_mgr_->GetDef(id);
if (!def || (def->opcode() != SpvOpSpecConstant && def->opcode() != SpvOpConstant) ||
(def->NumInOperands() != 1)) {
@@ -1336,7 +1336,7 @@
},
[&](const U32*) {
return create<ast::IntLiteralExpression>(
- Source{}, static_cast<uint64_t>(literal_value),
+ Source{}, static_cast<int64_t>(literal_value),
ast::IntLiteralExpression::Suffix::kU);
},
[&](const F32*) {
@@ -1715,8 +1715,8 @@
int member_index) {
// Yes, I could have used std::copy_if or std::copy_if.
DecorationList result;
- for (const auto& deco :
- GetDecorationsForMember(struct_id_for_symbol_[struct_type.name], member_index)) {
+ for (const auto& deco : GetDecorationsForMember(struct_id_for_symbol_[struct_type.name],
+ static_cast<uint32_t>(member_index))) {
if (IsPipelineDecoration(deco)) {
result.emplace_back(deco);
}
@@ -2721,7 +2721,7 @@
Fail() << "no structure type registered for symbol";
return "";
}
- return namer_.GetMemberName(where->second, member_index);
+ return namer_.GetMemberName(where->second, static_cast<uint32_t>(member_index));
}
WorkgroupSizeInfo::WorkgroupSizeInfo() = default;
diff --git a/src/tint/reader/spirv/parser_impl.h b/src/tint/reader/spirv/parser_impl.h
index 6addf6c..ce790d3 100644
--- a/src/tint/reader/spirv/parser_impl.h
+++ b/src/tint/reader/spirv/parser_impl.h
@@ -22,8 +22,18 @@
#include <utility>
#include <vector>
+#include "src/tint/utils/compiler_macros.h"
+
#if TINT_BUILD_SPV_READER
+TINT_BEGIN_DISABLE_WARNING(NEWLINE_EOF);
+TINT_BEGIN_DISABLE_WARNING(OLD_STYLE_CAST);
+TINT_BEGIN_DISABLE_WARNING(SIGN_CONVERSION);
+TINT_BEGIN_DISABLE_WARNING(WEAK_VTABLES);
#include "source/opt/ir_context.h"
+TINT_END_DISABLE_WARNING(WEAK_VTABLES);
+TINT_END_DISABLE_WARNING(SIGN_CONVERSION);
+TINT_END_DISABLE_WARNING(OLD_STYLE_CAST);
+TINT_END_DISABLE_WARNING(NEWLINE_EOF);
#endif
#include "src/tint/program_builder.h"
diff --git a/src/tint/reader/spirv/parser_impl_test_helper.h b/src/tint/reader/spirv/parser_impl_test_helper.h
index 7362a2d..f2c2dfe 100644
--- a/src/tint/reader/spirv/parser_impl_test_helper.h
+++ b/src/tint/reader/spirv/parser_impl_test_helper.h
@@ -21,8 +21,18 @@
#include <utility>
#include <vector>
+#include "src/tint/utils/compiler_macros.h"
+
#if TINT_BUILD_SPV_READER
+TINT_BEGIN_DISABLE_WARNING(NEWLINE_EOF);
+TINT_BEGIN_DISABLE_WARNING(OLD_STYLE_CAST);
+TINT_BEGIN_DISABLE_WARNING(SIGN_CONVERSION);
+TINT_BEGIN_DISABLE_WARNING(WEAK_VTABLES);
#include "source/opt/ir_context.h"
+TINT_END_DISABLE_WARNING(WEAK_VTABLES);
+TINT_END_DISABLE_WARNING(SIGN_CONVERSION);
+TINT_END_DISABLE_WARNING(OLD_STYLE_CAST);
+TINT_END_DISABLE_WARNING(NEWLINE_EOF);
#endif
#include "gtest/gtest.h"
diff --git a/src/tint/reader/spirv/parser_type.cc b/src/tint/reader/spirv/parser_type.cc
index 3332cd4..db8c01b 100644
--- a/src/tint/reader/spirv/parser_type.cc
+++ b/src/tint/reader/spirv/parser_type.cc
@@ -163,6 +163,12 @@
return b.ty.i32();
}
+Type::Type() = default;
+Type::Type(const Type&) = default;
+Type::~Type() = default;
+
+Texture::~Texture() = default;
+
Pointer::Pointer(const Type* t, ast::StorageClass s) : type(t), storage_class(s) {}
Pointer::Pointer(const Pointer&) = default;
diff --git a/src/tint/reader/spirv/parser_type.h b/src/tint/reader/spirv/parser_type.h
index 605ac9b..9543b51 100644
--- a/src/tint/reader/spirv/parser_type.h
+++ b/src/tint/reader/spirv/parser_type.h
@@ -40,6 +40,13 @@
/// Type is the base class for all types
class Type : public Castable<Type> {
public:
+ /// Constructor
+ Type();
+ /// Copy constructor
+ Type(const Type&);
+ /// Destructor
+ ~Type() override;
+
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
virtual const ast::Type* Build(ProgramBuilder& b) const = 0;
@@ -314,6 +321,8 @@
/// Base class for texture types
struct Texture : public Castable<Texture, Type> {
+ ~Texture() override;
+
/// Constructor
/// @param d the texture dimensions
explicit Texture(ast::TextureDimension d);
diff --git a/src/tint/reader/spirv/usage_test.cc b/src/tint/reader/spirv/usage_test.cc
index d01d1a2..bb64bb3 100644
--- a/src/tint/reader/spirv/usage_test.cc
+++ b/src/tint/reader/spirv/usage_test.cc
@@ -45,7 +45,7 @@
}
TEST_F(SpvParserTest, Usage_Equality_OneDifference) {
- const int num_usages = 9;
+ const size_t num_usages = 9u;
std::vector<Usage> usages(num_usages);
usages[1].AddSampler();
usages[2].AddComparisonSampler();
@@ -55,8 +55,8 @@
usages[6].AddDepthTexture();
usages[7].AddStorageReadTexture();
usages[8].AddStorageWriteTexture();
- for (int i = 0; i < num_usages; ++i) {
- for (int j = 0; j < num_usages; ++j) {
+ for (size_t i = 0; i < num_usages; ++i) {
+ for (size_t j = 0; j < num_usages; ++j) {
const auto& lhs = usages[i];
const auto& rhs = usages[j];
if (i == j) {
diff --git a/src/tint/reader/wgsl/lexer.cc b/src/tint/reader/wgsl/lexer.cc
index 716075e..ade723c 100644
--- a/src/tint/reader/wgsl/lexer.cc
+++ b/src/tint/reader/wgsl/lexer.cc
@@ -412,7 +412,7 @@
// clang-format on
// -?
- int64_t sign_bit = 0;
+ uint64_t sign_bit = 0;
if (matches(end, "-")) {
sign_bit = 1;
end++;
@@ -794,7 +794,7 @@
const bool overflow = errno == ERANGE;
if (end_ptr) {
- advance(end_ptr - start_ptr);
+ advance(static_cast<size_t>(end_ptr - start_ptr));
}
if (matches(pos(), "u")) {
@@ -1088,6 +1088,9 @@
if (str == "case") {
return {Token::Type::kCase, source, "case"};
}
+ if (str == "const") {
+ return {Token::Type::kConst, source, "const"};
+ }
if (str == "continue") {
return {Token::Type::kContinue, source, "continue"};
}
diff --git a/src/tint/reader/wgsl/lexer_test.cc b/src/tint/reader/wgsl/lexer_test.cc
index ab4ec7e..bf32a52 100644
--- a/src/tint/reader/wgsl/lexer_test.cc
+++ b/src/tint/reader/wgsl/lexer_test.cc
@@ -144,18 +144,18 @@
// Test that line comments are ended by blankspace characters other than
// space, horizontal tab, left-to-right mark, and right-to-left mark.
auto* c = GetParam();
- std::string src = "let// This is a comment";
+ std::string src = "const// This is a comment";
src += c;
src += "ident";
Source::File file("", src);
Lexer l(&file);
auto t = l.next();
- EXPECT_TRUE(t.Is(Token::Type::kLet));
+ EXPECT_TRUE(t.Is(Token::Type::kConst));
EXPECT_EQ(t.source().range.begin.line, 1u);
EXPECT_EQ(t.source().range.begin.column, 1u);
EXPECT_EQ(t.source().range.end.line, 1u);
- EXPECT_EQ(t.source().range.end.column, 4u);
+ EXPECT_EQ(t.source().range.end.column, 6u);
auto is_same_line = [](std::string_view v) {
return v == kSpace || v == kHTab || v == kL2R || v == kR2L;
@@ -930,6 +930,7 @@
TokenData{"bool", Token::Type::kBool},
TokenData{"break", Token::Type::kBreak},
TokenData{"case", Token::Type::kCase},
+ TokenData{"const", Token::Type::kConst},
TokenData{"continue", Token::Type::kContinue},
TokenData{"continuing", Token::Type::kContinuing},
TokenData{"default", Token::Type::kDefault},
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index 854b276..deaa17c 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -124,10 +124,10 @@
// https://gpuweb.github.io/gpuweb/wgsl.html#reserved-keywords
bool is_reserved(Token t) {
- return t == "asm" || t == "bf16" || t == "const" || t == "do" || t == "enum" || t == "f64" ||
- t == "handle" || t == "i8" || t == "i16" || t == "i64" || t == "mat" ||
- t == "premerge" || t == "regardless" || t == "typedef" || t == "u8" || t == "u16" ||
- t == "u64" || t == "unless" || t == "using" || t == "vec" || t == "void" || t == "while";
+ return t == "asm" || t == "bf16" || t == "do" || t == "enum" || t == "f64" || t == "handle" ||
+ t == "i8" || t == "i16" || t == "i64" || t == "mat" || t == "premerge" ||
+ t == "regardless" || t == "typedef" || t == "u8" || t == "u16" || t == "u64" ||
+ t == "unless" || t == "using" || t == "vec" || t == "void" || t == "while";
}
/// Enter-exit counters for block token types.
@@ -437,8 +437,12 @@
}
if (gc.matched) {
- if (!expect("'let' declaration", Token::Type::kSemicolon)) {
- return Failure::kErrored;
+ // Avoid the cost of the string allocation for the common no-error case
+ if (!peek().Is(Token::Type::kSemicolon)) {
+ std::string kind = gc->Kind();
+ if (!expect("'" + kind + "' declaration", Token::Type::kSemicolon)) {
+ return Failure::kErrored;
+ }
}
builder_.AST().AddGlobalVariable(gc.value);
@@ -537,13 +541,16 @@
return Failure::kNoMatch;
}
- const ast::Expression* constructor = nullptr;
+ const ast::Expression* initalizer = nullptr;
if (match(Token::Type::kEqual)) {
- auto expr = expect_const_expr();
+ auto expr = logical_or_expression();
if (expr.errored) {
return Failure::kErrored;
}
- constructor = expr.value;
+ if (!expr.matched) {
+ return add_error(peek(), "missing initalizer for 'var' declaration");
+ }
+ initalizer = expr.value;
}
return create<ast::Var>(decl->source, // source
@@ -551,7 +558,7 @@
decl->type, // type
decl->storage_class, // storage class
decl->access, // access control
- constructor, // constructor
+ initalizer, // constructor
std::move(attrs)); // attributes
}
@@ -561,10 +568,15 @@
// global_const_initializer
// : EQUAL const_expr
Maybe<const ast::Variable*> ParserImpl::global_constant_decl(ast::AttributeList& attrs) {
+ bool is_const = false;
bool is_overridable = false;
const char* use = nullptr;
- if (match(Token::Type::kLet)) {
+ Source source;
+ if (match(Token::Type::kConst)) {
+ use = "'const' declaration";
+ } else if (match(Token::Type::kLet, &source)) {
use = "'let' declaration";
+ deprecated(source, "module-scope 'let' has been replaced with 'const'");
} else if (match(Token::Type::kOverride)) {
use = "'override' declaration";
is_overridable = true;
@@ -589,13 +601,23 @@
const ast::Expression* initializer = nullptr;
if (has_initializer) {
- auto init = expect_const_expr();
- if (init.errored) {
+ auto expr = logical_or_expression();
+ if (expr.errored) {
return Failure::kErrored;
}
- initializer = std::move(init.value);
+ if (!expr.matched) {
+ return add_error(peek(), "missing initializer for " + std::string(use));
+ }
+ initializer = std::move(expr.value);
}
+ if (is_const) {
+ return create<ast::Const>(decl->source, // source
+ builder_.Symbols().Register(decl->name), // symbol
+ decl->type, // type
+ initializer, // constructor
+ std::move(attrs)); // attributes
+ }
if (is_overridable) {
return create<ast::Override>(decl->source, // source
builder_.Symbols().Register(decl->name), // symbol
@@ -603,16 +625,16 @@
initializer, // constructor
std::move(attrs)); // attributes
}
- return create<ast::Let>(decl->source, // source
- builder_.Symbols().Register(decl->name), // symbol
- decl->type, // type
- initializer, // constructor
- std::move(attrs)); // attributes
+ return create<ast::Const>(decl->source, // source
+ builder_.Symbols().Register(decl->name), // symbol
+ decl->type, // type
+ initializer, // constructor
+ std::move(attrs)); // attributes
}
// variable_decl
// : VAR variable_qualifier? variable_ident_decl
-Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl(bool allow_inferred) {
+Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl() {
Source source;
if (!match(Token::Type::kVar, &source)) {
return Failure::kNoMatch;
@@ -627,7 +649,8 @@
vq = explicit_vq.value;
}
- auto decl = expect_variable_ident_decl("variable declaration", allow_inferred);
+ auto decl = expect_variable_ident_decl("variable declaration",
+ /*allow_inferred = */ true);
if (decl.errored) {
return Failure::kErrored;
}
@@ -1350,7 +1373,8 @@
return Failure::kErrored;
}
- auto decl = expect_variable_ident_decl("struct member");
+ auto decl = expect_variable_ident_decl("struct member",
+ /*allow_inferred = */ false);
if (decl.errored) {
return Failure::kErrored;
}
@@ -1486,7 +1510,8 @@
Expect<ast::Parameter*> ParserImpl::expect_param() {
auto attrs = attribute_list();
- auto decl = expect_variable_ident_decl("parameter");
+ auto decl = expect_variable_ident_decl("parameter",
+ /*allow_inferred = */ false);
if (decl.errored) {
return Failure::kErrored;
}
@@ -1769,6 +1794,34 @@
// | variable_decl EQUAL logical_or_expression
// | CONST variable_ident_decl EQUAL logical_or_expression
Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
+ if (match(Token::Type::kConst)) {
+ auto decl = expect_variable_ident_decl("'const' declaration",
+ /*allow_inferred = */ true);
+ if (decl.errored) {
+ return Failure::kErrored;
+ }
+
+ if (!expect("'const' declaration", Token::Type::kEqual)) {
+ return Failure::kErrored;
+ }
+
+ auto constructor = logical_or_expression();
+ if (constructor.errored) {
+ return Failure::kErrored;
+ }
+ if (!constructor.matched) {
+ return add_error(peek(), "missing constructor for 'const' declaration");
+ }
+
+ auto* const_ = create<ast::Const>(decl->source, // source
+ builder_.Symbols().Register(decl->name), // symbol
+ decl->type, // type
+ constructor.value, // constructor
+ ast::AttributeList{}); // attributes
+
+ return create<ast::VariableDeclStatement>(decl->source, const_);
+ }
+
if (match(Token::Type::kLet)) {
auto decl = expect_variable_ident_decl("'let' declaration",
/*allow_inferred = */ true);
@@ -1797,7 +1850,7 @@
return create<ast::VariableDeclStatement>(decl->source, let);
}
- auto decl = variable_decl(/*allow_inferred = */ true);
+ auto decl = variable_decl();
if (decl.errored) {
return Failure::kErrored;
}
@@ -3065,58 +3118,6 @@
return Failure::kNoMatch;
}
-// const_expr
-// : type_decl PAREN_LEFT ((const_expr COMMA)? const_expr COMMA?)? PAREN_RIGHT
-// | const_literal
-Expect<const ast::Expression*> ParserImpl::expect_const_expr() {
- auto t = peek();
- auto source = t.source();
- if (t.IsLiteral()) {
- auto lit = const_literal();
- if (lit.errored) {
- return Failure::kErrored;
- }
- if (!lit.matched) {
- return add_error(peek(), "unable to parse constant literal");
- }
- return lit.value;
- }
-
- if (peek_is(Token::Type::kParenLeft, 1) || peek_is(Token::Type::kLessThan, 1)) {
- auto type = expect_type("const_expr");
- if (type.errored) {
- return Failure::kErrored;
- }
-
- auto params = expect_paren_block("type constructor", [&]() -> Expect<ast::ExpressionList> {
- ast::ExpressionList list;
- while (continue_parsing()) {
- if (peek_is(Token::Type::kParenRight)) {
- break;
- }
-
- auto arg = expect_const_expr();
- if (arg.errored) {
- return Failure::kErrored;
- }
- list.emplace_back(arg.value);
-
- if (!match(Token::Type::kComma)) {
- break;
- }
- }
- return list;
- });
-
- if (params.errored) {
- return Failure::kErrored;
- }
-
- return builder_.Construct(source, type.value, params.value);
- }
- return add_error(peek(), "unable to parse const_expr");
-}
-
Maybe<ast::AttributeList> ParserImpl::attribute_list() {
bool errored = false;
ast::AttributeList attrs;
diff --git a/src/tint/reader/wgsl/parser_impl.h b/src/tint/reader/wgsl/parser_impl.h
index c6e696b..5857454 100644
--- a/src/tint/reader/wgsl/parser_impl.h
+++ b/src/tint/reader/wgsl/parser_impl.h
@@ -388,18 +388,15 @@
/// @param attrs the list of attributes for the constant declaration.
Maybe<const ast::Variable*> global_constant_decl(ast::AttributeList& attrs);
/// Parses a `variable_decl` grammar element
- /// @param allow_inferred if true, do not fail if variable decl does not
- /// specify type
/// @returns the parsed variable declaration info
- Maybe<VarDeclInfo> variable_decl(bool allow_inferred = false);
+ Maybe<VarDeclInfo> variable_decl();
/// Parses a `variable_ident_decl` grammar element, erroring on parse
/// failure.
/// @param use a description of what was being parsed if an error was raised.
/// @param allow_inferred if true, do not fail if variable decl does not
/// specify type
/// @returns the identifier and type parsed or empty otherwise
- Expect<TypedIdentifier> expect_variable_ident_decl(std::string_view use,
- bool allow_inferred = false);
+ Expect<TypedIdentifier> expect_variable_ident_decl(std::string_view use, bool allow_inferred);
/// Parses a `variable_qualifier` grammar element
/// @returns the variable qualifier information
Maybe<VariableQualifier> variable_qualifier();
@@ -536,9 +533,6 @@
/// Parses a `const_literal` grammar element
/// @returns the const literal parsed or nullptr if none found
Maybe<const ast::LiteralExpression*> const_literal();
- /// Parses a `const_expr` grammar element, erroring on parse failure.
- /// @returns the parsed constructor expression or nullptr on error
- Expect<const ast::Expression*> expect_const_expr();
/// Parses a `primary_expression` grammar element
/// @returns the parsed expression or nullptr
Maybe<const ast::Expression*> primary_expression();
diff --git a/src/tint/reader/wgsl/parser_impl_const_expr_test.cc b/src/tint/reader/wgsl/parser_impl_const_expr_test.cc
deleted file mode 100644
index 80536bd..0000000
--- a/src/tint/reader/wgsl/parser_impl_const_expr_test.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2020 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/reader/wgsl/parser_impl_test_helper.h"
-
-namespace tint::reader::wgsl {
-namespace {
-
-TEST_F(ParserImplTest, ConstExpr_TypeDecl) {
- auto p = parser("vec2<f32>(1., 2.)");
- auto e = p->expect_const_expr();
- ASSERT_FALSE(p->has_error()) << p->error();
- ASSERT_FALSE(e.errored);
- ASSERT_TRUE(e->Is<ast::CallExpression>());
-
- auto* t = e->As<ast::CallExpression>();
- ASSERT_TRUE(t->target.type->Is<ast::Vector>());
- EXPECT_EQ(t->target.type->As<ast::Vector>()->width, 2u);
-
- ASSERT_EQ(t->args.size(), 2u);
-
- ASSERT_TRUE(t->args[0]->Is<ast::FloatLiteralExpression>());
- EXPECT_DOUBLE_EQ(t->args[0]->As<ast::FloatLiteralExpression>()->value, 1.);
- EXPECT_EQ(t->args[0]->As<ast::FloatLiteralExpression>()->suffix,
- ast::FloatLiteralExpression::Suffix::kNone);
-
- ASSERT_TRUE(t->args[1]->Is<ast::FloatLiteralExpression>());
- EXPECT_DOUBLE_EQ(t->args[1]->As<ast::FloatLiteralExpression>()->value, 2.);
- EXPECT_EQ(t->args[1]->As<ast::FloatLiteralExpression>()->suffix,
- ast::FloatLiteralExpression::Suffix::kNone);
-}
-
-TEST_F(ParserImplTest, ConstExpr_TypeDecl_Empty) {
- auto p = parser("vec2<f32>()");
- auto e = p->expect_const_expr();
- ASSERT_FALSE(p->has_error()) << p->error();
- ASSERT_FALSE(e.errored);
- ASSERT_TRUE(e->Is<ast::CallExpression>());
-
- auto* t = e->As<ast::CallExpression>();
- ASSERT_TRUE(t->target.type->Is<ast::Vector>());
- EXPECT_EQ(t->target.type->As<ast::Vector>()->width, 2u);
-
- ASSERT_EQ(t->args.size(), 0u);
-}
-
-TEST_F(ParserImplTest, ConstExpr_TypeDecl_TrailingComma) {
- auto p = parser("vec2<f32>(1., 2.,)");
- auto e = p->expect_const_expr();
- ASSERT_FALSE(p->has_error()) << p->error();
- ASSERT_FALSE(e.errored);
- ASSERT_TRUE(e->Is<ast::CallExpression>());
-
- auto* t = e->As<ast::CallExpression>();
- ASSERT_TRUE(t->target.type->Is<ast::Vector>());
- EXPECT_EQ(t->target.type->As<ast::Vector>()->width, 2u);
-
- ASSERT_EQ(t->args.size(), 2u);
- ASSERT_TRUE(t->args[0]->Is<ast::LiteralExpression>());
- ASSERT_TRUE(t->args[1]->Is<ast::LiteralExpression>());
-}
-
-TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingRightParen) {
- auto p = parser("vec2<f32>(1., 2.");
- auto e = p->expect_const_expr();
- ASSERT_TRUE(p->has_error());
- ASSERT_TRUE(e.errored);
- ASSERT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:17: expected ')' for type constructor");
-}
-
-TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingLeftParen) {
- auto p = parser("vec2<f32> 1., 2.)");
- auto e = p->expect_const_expr();
- ASSERT_TRUE(p->has_error());
- ASSERT_TRUE(e.errored);
- ASSERT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:11: expected '(' for type constructor");
-}
-
-TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingComma) {
- auto p = parser("vec2<f32>(1. 2.");
- auto e = p->expect_const_expr();
- ASSERT_TRUE(p->has_error());
- ASSERT_TRUE(e.errored);
- ASSERT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:14: expected ')' for type constructor");
-}
-
-TEST_F(ParserImplTest, ConstExpr_InvalidExpr) {
- auto p = parser("vec2<f32>(1., if(a) {})");
- auto e = p->expect_const_expr();
- ASSERT_TRUE(p->has_error());
- ASSERT_TRUE(e.errored);
- ASSERT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:15: invalid type for const_expr");
-}
-
-TEST_F(ParserImplTest, ConstExpr_ConstLiteral) {
- auto p = parser("true");
- auto e = p->expect_const_expr();
- ASSERT_FALSE(p->has_error()) << p->error();
- ASSERT_FALSE(e.errored);
- ASSERT_NE(e.value, nullptr);
- ASSERT_TRUE(e.value->Is<ast::BoolLiteralExpression>());
- EXPECT_TRUE(e.value->As<ast::BoolLiteralExpression>()->value);
-}
-
-TEST_F(ParserImplTest, ConstExpr_ConstLiteral_Invalid) {
- auto p = parser("invalid");
- auto e = p->expect_const_expr();
- ASSERT_TRUE(p->has_error());
- ASSERT_TRUE(e.errored);
- ASSERT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:1: unable to parse const_expr");
-}
-
-TEST_F(ParserImplTest, ConstExpr_TypeConstructor) {
- auto p = parser("S(0)");
-
- auto e = p->expect_const_expr();
- ASSERT_FALSE(e.errored);
- ASSERT_TRUE(e->Is<ast::CallExpression>());
- ASSERT_NE(e->As<ast::CallExpression>()->target.type, nullptr);
- ASSERT_TRUE(e->As<ast::CallExpression>()->target.type->Is<ast::TypeName>());
- EXPECT_EQ(e->As<ast::CallExpression>()->target.type->As<ast::TypeName>()->name,
- p->builder().Symbols().Get("S"));
-}
-
-TEST_F(ParserImplTest, ConstExpr_Recursion) {
- std::stringstream out;
- for (size_t i = 0; i < 200; i++) {
- out << "f32(";
- }
- out << "1.0";
- for (size_t i = 0; i < 200; i++) {
- out << ")";
- }
- auto p = parser(out.str());
- auto e = p->expect_const_expr();
- ASSERT_TRUE(p->has_error());
- ASSERT_TRUE(e.errored);
- ASSERT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:517: maximum parser recursive depth reached");
-}
-
-TEST_F(ParserImplTest, UnaryOp_Recursion) {
- std::stringstream out;
- for (size_t i = 0; i < 200; i++) {
- out << "!";
- }
- out << "1.0";
- auto p = parser(out.str());
- auto e = p->unary_expression();
- ASSERT_TRUE(p->has_error());
- ASSERT_TRUE(e.errored);
- ASSERT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:130: maximum parser recursive depth reached");
-}
-
-} // namespace
-} // namespace tint::reader::wgsl
diff --git a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
index fc141c0..48969a5 100644
--- a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
@@ -456,75 +456,54 @@
}
TEST_F(ParserImplErrorTest, FunctionMissingOpenLine) {
- EXPECT(R"(let bar : vec2<f32> = vec2<f32>(1., 2.);
+ EXPECT(
+ R"(const bar : vec2<f32> = vec2<f32>(1., 2.);
var a : f32 = bar[0];
return;
})",
- R"(test.wgsl:2:17 error: unable to parse const_expr
- var a : f32 = bar[0];
- ^^^
-
-test.wgsl:3:3 error: statement found outside of function body
+ R"(test.wgsl:3:3 error: statement found outside of function body
return;
^^^^^^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclConstInvalidIdentifier) {
- EXPECT("let ^ : i32 = 1;",
- R"(test.wgsl:1:5 error: expected identifier for 'let' declaration
-let ^ : i32 = 1;
- ^
+ EXPECT("const ^ : i32 = 1;",
+ R"(test.wgsl:1:7 error: expected identifier for 'const' declaration
+const ^ : i32 = 1;
+ ^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclConstMissingSemicolon) {
- EXPECT("let i : i32 = 1",
- R"(test.wgsl:1:16 error: expected ';' for 'let' declaration
-let i : i32 = 1
- ^
+ EXPECT("const i : i32 = 1",
+ R"(test.wgsl:1:18 error: expected ';' for 'const' declaration
+const i : i32 = 1
+ ^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclConstMissingLParen) {
- EXPECT("let i : vec2<i32> = vec2<i32>;",
- R"(test.wgsl:1:30 error: expected '(' for type constructor
-let i : vec2<i32> = vec2<i32>;
- ^
+ EXPECT("const i : vec2<i32> = vec2<i32>;",
+ R"(test.wgsl:1:32 error: expected '(' for type constructor
+const i : vec2<i32> = vec2<i32>;
+ ^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclConstMissingRParen) {
- EXPECT("let i : vec2<i32> = vec2<i32>(1., 2.;",
- R"(test.wgsl:1:37 error: expected ')' for type constructor
-let i : vec2<i32> = vec2<i32>(1., 2.;
- ^
+ EXPECT("const i : vec2<i32> = vec2<i32>(1., 2.;",
+ R"(test.wgsl:1:39 error: expected ')' for type constructor
+const i : vec2<i32> = vec2<i32>(1., 2.;
+ ^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclConstBadConstLiteral) {
- EXPECT("let i : vec2<i32> = vec2<i32>(!);",
- R"(test.wgsl:1:31 error: unable to parse const_expr
-let i : vec2<i32> = vec2<i32>(!);
- ^
-)");
-}
-
-TEST_F(ParserImplErrorTest, GlobalDeclConstBadConstLiteralSpaceLessThan) {
- EXPECT("let i = 1 < 2;",
- R"(test.wgsl:1:11 error: expected ';' for 'let' declaration
-let i = 1 < 2;
- ^
-)");
-}
-
-TEST_F(ParserImplErrorTest, GlobalDeclConstNotConstExpr) {
- EXPECT(
- "let a = 1;\n"
- "let b = a;",
- R"(test.wgsl:2:9 error: unable to parse const_expr
-let b = a;
- ^
+ EXPECT("const i : vec2<i32> = vec2<i32>(!);",
+ R"(test.wgsl:1:34 error: unable to parse right side of ! expression
+const i : vec2<i32> = vec2<i32>(!);
+ ^
)");
}
@@ -533,8 +512,8 @@
std::stringstream src;
std::stringstream mkr;
- src << "let i : i32 = ";
- mkr << " ";
+ src << "const i : i32 = ";
+ mkr << " ";
for (size_t i = 0; i < kMaxDepth + 8; i++) {
src << "f32(";
if (i < kMaxDepth) {
@@ -549,23 +528,113 @@
}
src << ";";
std::stringstream err;
- err << "test.wgsl:1:527 error: maximum parser recursive depth reached\n"
+ err << "test.wgsl:1:529 error: maximum parser recursive depth reached\n"
<< src.str() << "\n"
<< mkr.str() << "\n";
EXPECT(src.str().c_str(), err.str().c_str());
}
TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingLParen) {
- EXPECT("let i : vec2<i32> = vec2<i32> 1, 2);",
- R"(test.wgsl:1:31 error: expected '(' for type constructor
+ EXPECT("const i : vec2<i32> = vec2<i32> 1, 2);",
+ R"(test.wgsl:1:33 error: expected '(' for type constructor
+const i : vec2<i32> = vec2<i32> 1, 2);
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingRParen) {
+ EXPECT("const i : vec2<i32> = vec2<i32>(1, 2;",
+ R"(test.wgsl:1:37 error: expected ')' for type constructor
+const i : vec2<i32> = vec2<i32>(1, 2;
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclLetInvalidIdentifier) {
+ EXPECT(
+ "let ^ : i32 = 1;",
+ R"(test.wgsl:1:1 warning: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+let ^ : i32 = 1;
+^^^
+
+test.wgsl:1:5 error: expected identifier for 'let' declaration
+let ^ : i32 = 1;
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclLetMissingSemicolon) {
+ EXPECT(
+ "let i : i32 = 1",
+ R"(test.wgsl:1:1 warning: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+let i : i32 = 1
+^^^
+
+test.wgsl:1:16 error: expected ';' for 'const' declaration
+let i : i32 = 1
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclLetMissingLParen) {
+ EXPECT(
+ "let i : vec2<i32> = vec2<i32>;",
+ R"(test.wgsl:1:1 warning: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+let i : vec2<i32> = vec2<i32>;
+^^^
+
+test.wgsl:1:30 error: expected '(' for type constructor
+let i : vec2<i32> = vec2<i32>;
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclLetMissingRParen) {
+ EXPECT(
+ "let i : vec2<i32> = vec2<i32>(1., 2.;",
+ R"(test.wgsl:1:1 warning: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+let i : vec2<i32> = vec2<i32>(1., 2.;
+^^^
+
+test.wgsl:1:37 error: expected ')' for type constructor
+let i : vec2<i32> = vec2<i32>(1., 2.;
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclLetBadConstLiteral) {
+ EXPECT("let i : vec2<i32> = vec2<i32>(!);",
+ R"(test.wgsl:1:1 warning: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+let i : vec2<i32> = vec2<i32>(!);
+^^^
+
+test.wgsl:1:32 error: unable to parse right side of ! expression
+let i : vec2<i32> = vec2<i32>(!);
+ ^
+)");
+}
+
+TEST_F(ParserImplErrorTest, GlobalDeclLetExprMissingLParen) {
+ EXPECT(
+ "let i : vec2<i32> = vec2<i32> 1, 2);",
+ R"(test.wgsl:1:1 warning: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+let i : vec2<i32> = vec2<i32> 1, 2);
+^^^
+
+test.wgsl:1:31 error: expected '(' for type constructor
let i : vec2<i32> = vec2<i32> 1, 2);
^
)");
}
-TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingRParen) {
- EXPECT("let i : vec2<i32> = vec2<i32>(1, 2;",
- R"(test.wgsl:1:35 error: expected ')' for type constructor
+TEST_F(ParserImplErrorTest, GlobalDeclLetExprMissingRParen) {
+ EXPECT(
+ "let i : vec2<i32> = vec2<i32>(1, 2;",
+ R"(test.wgsl:1:1 warning: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+let i : vec2<i32> = vec2<i32>(1, 2;
+^^^
+
+test.wgsl:1:35 error: expected ')' for type constructor
let i : vec2<i32> = vec2<i32>(1, 2;
^
)");
diff --git a/src/tint/reader/wgsl/parser_impl_global_constant_decl_test.cc b/src/tint/reader/wgsl/parser_impl_global_constant_decl_test.cc
index f5428fc..bfa678e 100644
--- a/src/tint/reader/wgsl/parser_impl_global_constant_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_global_constant_decl_test.cc
@@ -18,7 +18,7 @@
namespace tint::reader::wgsl {
namespace {
-TEST_F(ParserImplTest, GlobalConstantDecl) {
+TEST_F(ParserImplTest, GlobalLetDecl) {
auto p = parser("let a : f32 = 1.");
auto attrs = p->attribute_list();
EXPECT_FALSE(attrs.errored);
@@ -27,23 +27,23 @@
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
- auto* let = e.value->As<ast::Let>();
- ASSERT_NE(let, nullptr);
+ auto* const_ = e.value->As<ast::Const>();
+ ASSERT_NE(const_, nullptr);
- EXPECT_EQ(let->symbol, p->builder().Symbols().Get("a"));
- ASSERT_NE(let->type, nullptr);
- EXPECT_TRUE(let->type->Is<ast::F32>());
+ EXPECT_EQ(const_->symbol, p->builder().Symbols().Get("a"));
+ ASSERT_NE(const_->type, nullptr);
+ EXPECT_TRUE(const_->type->Is<ast::F32>());
- EXPECT_EQ(let->source.range.begin.line, 1u);
- EXPECT_EQ(let->source.range.begin.column, 5u);
- EXPECT_EQ(let->source.range.end.line, 1u);
- EXPECT_EQ(let->source.range.end.column, 6u);
+ EXPECT_EQ(const_->source.range.begin.line, 1u);
+ EXPECT_EQ(const_->source.range.begin.column, 5u);
+ EXPECT_EQ(const_->source.range.end.line, 1u);
+ EXPECT_EQ(const_->source.range.end.column, 6u);
- ASSERT_NE(let->constructor, nullptr);
- EXPECT_TRUE(let->constructor->Is<ast::LiteralExpression>());
+ ASSERT_NE(const_->constructor, nullptr);
+ EXPECT_TRUE(const_->constructor->Is<ast::LiteralExpression>());
}
-TEST_F(ParserImplTest, GlobalConstantDecl_Inferred) {
+TEST_F(ParserImplTest, GlobalLetDecl_Inferred) {
auto p = parser("let a = 1.");
auto attrs = p->attribute_list();
EXPECT_FALSE(attrs.errored);
@@ -52,22 +52,22 @@
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
- auto* let = e.value->As<ast::Let>();
- ASSERT_NE(let, nullptr);
+ auto* const_ = e.value->As<ast::Const>();
+ ASSERT_NE(const_, nullptr);
- EXPECT_EQ(let->symbol, p->builder().Symbols().Get("a"));
- EXPECT_EQ(let->type, nullptr);
+ EXPECT_EQ(const_->symbol, p->builder().Symbols().Get("a"));
+ EXPECT_EQ(const_->type, nullptr);
- EXPECT_EQ(let->source.range.begin.line, 1u);
- EXPECT_EQ(let->source.range.begin.column, 5u);
- EXPECT_EQ(let->source.range.end.line, 1u);
- EXPECT_EQ(let->source.range.end.column, 6u);
+ EXPECT_EQ(const_->source.range.begin.line, 1u);
+ EXPECT_EQ(const_->source.range.begin.column, 5u);
+ EXPECT_EQ(const_->source.range.end.line, 1u);
+ EXPECT_EQ(const_->source.range.end.column, 6u);
- ASSERT_NE(let->constructor, nullptr);
- EXPECT_TRUE(let->constructor->Is<ast::LiteralExpression>());
+ ASSERT_NE(const_->constructor, nullptr);
+ EXPECT_TRUE(const_->constructor->Is<ast::LiteralExpression>());
}
-TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
+TEST_F(ParserImplTest, GlobalLetDecl_InvalidExpression) {
auto p = parser("let a : f32 = if (a) {}");
auto attrs = p->attribute_list();
EXPECT_FALSE(attrs.errored);
@@ -77,10 +77,13 @@
EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:15: invalid type for const_expr");
+ EXPECT_EQ(
+ p->error(),
+ R"(1:1: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+1:15: missing initializer for 'let' declaration)");
}
-TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
+TEST_F(ParserImplTest, GlobalLetDecl_MissingExpression) {
auto p = parser("let a : f32 =");
auto attrs = p->attribute_list();
EXPECT_FALSE(attrs.errored);
@@ -90,10 +93,88 @@
EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:14: unable to parse const_expr");
+ EXPECT_EQ(
+ p->error(),
+ R"(1:1: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+1:14: missing initializer for 'let' declaration)");
}
-TEST_F(ParserImplTest, GlobalConstantDec_Override_WithId) {
+TEST_F(ParserImplTest, GlobalConstDecl) {
+ auto p = parser("const a : f32 = 1.");
+ auto attrs = p->attribute_list();
+ EXPECT_FALSE(attrs.errored);
+ EXPECT_FALSE(attrs.matched);
+ auto e = p->global_constant_decl(attrs.value);
+ EXPECT_FALSE(p->has_error()) << p->error();
+ EXPECT_TRUE(e.matched);
+ EXPECT_FALSE(e.errored);
+ auto* c = e.value->As<ast::Const>();
+ ASSERT_NE(c, nullptr);
+
+ EXPECT_EQ(c->symbol, p->builder().Symbols().Get("a"));
+ ASSERT_NE(c->type, nullptr);
+ EXPECT_TRUE(c->type->Is<ast::F32>());
+
+ EXPECT_EQ(c->source.range.begin.line, 1u);
+ EXPECT_EQ(c->source.range.begin.column, 7u);
+ EXPECT_EQ(c->source.range.end.line, 1u);
+ EXPECT_EQ(c->source.range.end.column, 8u);
+
+ ASSERT_NE(c->constructor, nullptr);
+ EXPECT_TRUE(c->constructor->Is<ast::LiteralExpression>());
+}
+
+TEST_F(ParserImplTest, GlobalConstDecl_Inferred) {
+ auto p = parser("const a = 1.");
+ auto attrs = p->attribute_list();
+ EXPECT_FALSE(attrs.errored);
+ EXPECT_FALSE(attrs.matched);
+ auto e = p->global_constant_decl(attrs.value);
+ EXPECT_FALSE(p->has_error()) << p->error();
+ EXPECT_TRUE(e.matched);
+ EXPECT_FALSE(e.errored);
+ auto* c = e.value->As<ast::Const>();
+ ASSERT_NE(c, nullptr);
+
+ EXPECT_EQ(c->symbol, p->builder().Symbols().Get("a"));
+ EXPECT_EQ(c->type, nullptr);
+
+ EXPECT_EQ(c->source.range.begin.line, 1u);
+ EXPECT_EQ(c->source.range.begin.column, 7u);
+ EXPECT_EQ(c->source.range.end.line, 1u);
+ EXPECT_EQ(c->source.range.end.column, 8u);
+
+ ASSERT_NE(c->constructor, nullptr);
+ EXPECT_TRUE(c->constructor->Is<ast::LiteralExpression>());
+}
+
+TEST_F(ParserImplTest, GlobalConstDecl_InvalidExpression) {
+ auto p = parser("const a : f32 = if (a) {}");
+ auto attrs = p->attribute_list();
+ EXPECT_FALSE(attrs.errored);
+ EXPECT_FALSE(attrs.matched);
+ auto e = p->global_constant_decl(attrs.value);
+ EXPECT_TRUE(p->has_error());
+ EXPECT_TRUE(e.errored);
+ EXPECT_FALSE(e.matched);
+ EXPECT_EQ(e.value, nullptr);
+ EXPECT_EQ(p->error(), "1:17: missing initializer for 'const' declaration");
+}
+
+TEST_F(ParserImplTest, GlobalConstDecl_MissingExpression) {
+ auto p = parser("const a : f32 =");
+ auto attrs = p->attribute_list();
+ EXPECT_FALSE(attrs.errored);
+ EXPECT_FALSE(attrs.matched);
+ auto e = p->global_constant_decl(attrs.value);
+ EXPECT_TRUE(p->has_error());
+ EXPECT_TRUE(e.errored);
+ EXPECT_FALSE(e.matched);
+ EXPECT_EQ(e.value, nullptr);
+ EXPECT_EQ(p->error(), "1:16: missing initializer for 'const' declaration");
+}
+
+TEST_F(ParserImplTest, GlobalOverrideDecl_WithId) {
auto p = parser("@id(7) override a : f32 = 1.");
auto attrs = p->attribute_list();
EXPECT_FALSE(attrs.errored);
@@ -123,7 +204,7 @@
EXPECT_EQ(override_attr->value, 7u);
}
-TEST_F(ParserImplTest, GlobalConstantDec_Override_WithoutId) {
+TEST_F(ParserImplTest, GlobalOverrideDecl_WithoutId) {
auto p = parser("override a : f32 = 1.");
auto attrs = p->attribute_list();
EXPECT_FALSE(attrs.errored);
@@ -152,7 +233,7 @@
ASSERT_EQ(id_attr, nullptr);
}
-TEST_F(ParserImplTest, GlobalConstantDec_Override_MissingId) {
+TEST_F(ParserImplTest, GlobalOverrideDecl_MissingId) {
auto p = parser("@id() override a : f32 = 1.");
auto attrs = p->attribute_list();
EXPECT_TRUE(attrs.errored);
@@ -168,7 +249,7 @@
EXPECT_EQ(p->error(), "1:5: expected signed integer literal for id attribute");
}
-TEST_F(ParserImplTest, GlobalConstantDec_Override_InvalidId) {
+TEST_F(ParserImplTest, GlobalOverrideDecl_InvalidId) {
auto p = parser("@id(-7) override a : f32 = 1.");
auto attrs = p->attribute_list();
EXPECT_TRUE(attrs.errored);
diff --git a/src/tint/reader/wgsl/parser_impl_global_decl_test.cc b/src/tint/reader/wgsl/parser_impl_global_decl_test.cc
index 59012a3..5abe58f 100644
--- a/src/tint/reader/wgsl/parser_impl_global_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_global_decl_test.cc
@@ -33,13 +33,20 @@
auto* v = program.AST().GlobalVariables()[0];
EXPECT_EQ(v->symbol, program.Symbols().Get("a"));
+ EXPECT_TRUE(Is<ast::Vector>(v->type));
}
-TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_Inferred_Invalid) {
+TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_Inferred) {
auto p = parser("var<private> a = vec2<i32>(1, 2);");
p->global_decl();
- ASSERT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:16: expected ':' for variable declaration");
+ ASSERT_FALSE(p->has_error()) << p->error();
+
+ auto program = p->program();
+ ASSERT_EQ(program.AST().GlobalVariables().size(), 1u);
+
+ auto* v = program.AST().GlobalVariables()[0];
+ EXPECT_EQ(v->symbol, program.Symbols().Get("a"));
+ EXPECT_EQ(v->type, nullptr);
}
TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_MissingSemicolon) {
@@ -49,7 +56,7 @@
EXPECT_EQ(p->error(), "1:27: expected ';' for variable declaration");
}
-TEST_F(ParserImplTest, GlobalDecl_GlobalConstant) {
+TEST_F(ParserImplTest, GlobalDecl_GlobalLet) {
auto p = parser("let a : i32 = 2;");
p->global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
@@ -61,25 +68,67 @@
EXPECT_EQ(v->symbol, program.Symbols().Get("a"));
}
-TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_MissingInitializer) {
+TEST_F(ParserImplTest, GlobalDecl_GlobalLet_MissingInitializer) {
auto p = parser("let a : vec2<i32>;");
p->global_decl();
ASSERT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:18: expected '=' for 'let' declaration");
+ EXPECT_EQ(
+ p->error(),
+ R"(1:1: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+1:18: expected '=' for 'let' declaration)");
}
-TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_Invalid) {
+TEST_F(ParserImplTest, GlobalDecl_GlobalLet_Invalid) {
auto p = parser("let a : vec2<i32> 1.0;");
p->global_decl();
ASSERT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:19: expected '=' for 'let' declaration");
+ EXPECT_EQ(
+ p->error(),
+ R"(1:1: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+1:19: expected '=' for 'let' declaration)");
}
-TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_MissingSemicolon) {
+TEST_F(ParserImplTest, GlobalDecl_GlobalLet_MissingSemicolon) {
auto p = parser("let a : vec2<i32> = vec2<i32>(1, 2)");
p->global_decl();
ASSERT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:36: expected ';' for 'let' declaration");
+ EXPECT_EQ(
+ p->error(),
+ R"(1:1: use of deprecated language feature: module-scope 'let' has been replaced with 'const'
+1:36: expected ';' for 'const' declaration)");
+}
+
+TEST_F(ParserImplTest, GlobalDecl_GlobalConst) {
+ auto p = parser("const a : i32 = 2;");
+ p->global_decl();
+ ASSERT_FALSE(p->has_error()) << p->error();
+
+ auto program = p->program();
+ ASSERT_EQ(program.AST().GlobalVariables().size(), 1u);
+
+ auto* v = program.AST().GlobalVariables()[0];
+ EXPECT_EQ(v->symbol, program.Symbols().Get("a"));
+}
+
+TEST_F(ParserImplTest, GlobalDecl_GlobalConst_MissingInitializer) {
+ auto p = parser("const a : vec2<i32>;");
+ p->global_decl();
+ ASSERT_TRUE(p->has_error());
+ EXPECT_EQ(p->error(), "1:20: expected '=' for 'const' declaration");
+}
+
+TEST_F(ParserImplTest, GlobalDecl_GlobalConst_Invalid) {
+ auto p = parser("const a : vec2<i32> 1.0;");
+ p->global_decl();
+ ASSERT_TRUE(p->has_error());
+ EXPECT_EQ(p->error(), "1:21: expected '=' for 'const' declaration");
+}
+
+TEST_F(ParserImplTest, GlobalDecl_GlobalConst_MissingSemicolon) {
+ auto p = parser("const a : vec2<i32> = vec2<i32>(1, 2)");
+ p->global_decl();
+ ASSERT_TRUE(p->has_error());
+ EXPECT_EQ(p->error(), "1:38: expected ';' for 'const' declaration");
}
TEST_F(ParserImplTest, GlobalDecl_TypeAlias) {
diff --git a/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc b/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
index 11371e6..f671042 100644
--- a/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
@@ -152,7 +152,7 @@
EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr);
- EXPECT_EQ(p->error(), "1:24: invalid type for const_expr");
+ EXPECT_EQ(p->error(), "1:24: missing initalizer for 'var' declaration");
}
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {
diff --git a/src/tint/reader/wgsl/parser_impl_reserved_keyword_test.cc b/src/tint/reader/wgsl/parser_impl_reserved_keyword_test.cc
index 8da2771..cb61eed 100644
--- a/src/tint/reader/wgsl/parser_impl_reserved_keyword_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_reserved_keyword_test.cc
@@ -25,12 +25,12 @@
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:4: '" + name + "' is a reserved keyword");
}
-TEST_P(ParserImplReservedKeywordTest, ModuleLet) {
+TEST_P(ParserImplReservedKeywordTest, ModuleConst) {
auto name = GetParam();
- auto p = parser("let " + name + " : i32 = 1;");
+ auto p = parser("const " + name + " : i32 = 1;");
EXPECT_FALSE(p->Parse());
EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:5: '" + name + "' is a reserved keyword");
+ EXPECT_EQ(p->error(), "1:7: '" + name + "' is a reserved keyword");
}
TEST_P(ParserImplReservedKeywordTest, ModuleVar) {
auto name = GetParam();
@@ -85,7 +85,6 @@
ParserImplReservedKeywordTest,
testing::Values("asm",
"bf16",
- "const",
"do",
"enum",
"f64",
diff --git a/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc b/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
index 70ec394..39f8b24 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
@@ -51,7 +51,7 @@
TEST_F(ParserImplTest, VariableDecl_Inferred_Parses) {
auto p = parser("var my_var = 1.0");
- auto v = p->variable_decl(/*allow_inferred = */ true);
+ auto v = p->variable_decl();
EXPECT_FALSE(p->has_error());
EXPECT_TRUE(v.matched);
EXPECT_FALSE(v.errored);
@@ -72,15 +72,6 @@
ASSERT_TRUE(t.IsIdentifier());
}
-TEST_F(ParserImplTest, VariableDecl_InvalidIdentDecl) {
- auto p = parser("var my_var f32");
- auto v = p->variable_decl();
- EXPECT_FALSE(v.matched);
- EXPECT_TRUE(v.errored);
- EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:12: expected ':' for variable declaration");
-}
-
TEST_F(ParserImplTest, VariableDecl_WithStorageClass) {
auto p = parser("var<private> my_var : f32");
auto v = p->variable_decl();
diff --git a/src/tint/reader/wgsl/parser_impl_variable_ident_decl_test.cc b/src/tint/reader/wgsl/parser_impl_variable_ident_decl_test.cc
index 3ffb29e..a811a82 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_ident_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_ident_decl_test.cc
@@ -19,7 +19,7 @@
TEST_F(ParserImplTest, VariableIdentDecl_Parses) {
auto p = parser("my_var : f32");
- auto decl = p->expect_variable_ident_decl("test");
+ auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ false);
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var");
@@ -30,7 +30,27 @@
EXPECT_EQ(decl->type->source.range, (Source::Range{{1u, 10u}, {1u, 13u}}));
}
-TEST_F(ParserImplTest, VariableIdentDecl_Inferred_Parses) {
+TEST_F(ParserImplTest, VariableIdentDecl_Parses_AllowInferredType) {
+ auto p = parser("my_var : f32");
+ auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ true);
+ ASSERT_FALSE(p->has_error()) << p->error();
+ ASSERT_FALSE(decl.errored);
+ ASSERT_EQ(decl->name, "my_var");
+ ASSERT_NE(decl->type, nullptr);
+ ASSERT_TRUE(decl->type->Is<ast::F32>());
+
+ EXPECT_EQ(decl->source.range, (Source::Range{{1u, 1u}, {1u, 7u}}));
+ EXPECT_EQ(decl->type->source.range, (Source::Range{{1u, 10u}, {1u, 13u}}));
+}
+
+TEST_F(ParserImplTest, VariableIdentDecl_Inferred_Parse_Failure) {
+ auto p = parser("my_var = 1.0");
+ auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ false);
+ ASSERT_TRUE(p->has_error());
+ ASSERT_EQ(p->error(), "1:8: expected ':' for test");
+}
+
+TEST_F(ParserImplTest, VariableIdentDecl_Inferred_Parses_AllowInferredType) {
auto p = parser("my_var = 1.0");
auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ true);
ASSERT_FALSE(p->has_error()) << p->error();
@@ -43,23 +63,31 @@
TEST_F(ParserImplTest, VariableIdentDecl_MissingIdent) {
auto p = parser(": f32");
- auto decl = p->expect_variable_ident_decl("test");
+ auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ false);
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:1: expected identifier for test");
}
-TEST_F(ParserImplTest, VariableIdentDecl_MissingColon) {
- auto p = parser("my_var f32");
- auto decl = p->expect_variable_ident_decl("test");
+TEST_F(ParserImplTest, VariableIdentDecl_MissingIdent_AllowInferredType) {
+ auto p = parser(": f32");
+ auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ true);
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored);
- ASSERT_EQ(p->error(), "1:8: expected ':' for test");
+ ASSERT_EQ(p->error(), "1:1: expected identifier for test");
}
TEST_F(ParserImplTest, VariableIdentDecl_MissingType) {
auto p = parser("my_var :");
- auto decl = p->expect_variable_ident_decl("test");
+ auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ false);
+ ASSERT_TRUE(p->has_error());
+ ASSERT_TRUE(decl.errored);
+ ASSERT_EQ(p->error(), "1:9: invalid type for test");
+}
+
+TEST_F(ParserImplTest, VariableIdentDecl_MissingType_AllowInferredType) {
+ auto p = parser("my_var :");
+ auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ true);
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:9: invalid type for test");
@@ -67,7 +95,15 @@
TEST_F(ParserImplTest, VariableIdentDecl_InvalidIdent) {
auto p = parser("123 : f32");
- auto decl = p->expect_variable_ident_decl("test");
+ auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ false);
+ ASSERT_TRUE(p->has_error());
+ ASSERT_TRUE(decl.errored);
+ ASSERT_EQ(p->error(), "1:1: expected identifier for test");
+}
+
+TEST_F(ParserImplTest, VariableIdentDecl_InvalidIdent_AllowInferredType) {
+ auto p = parser("123 : f32");
+ auto decl = p->expect_variable_ident_decl("test", /*allow_inferred = */ true);
ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:1: expected identifier for test");
diff --git a/src/tint/reader/wgsl/token.cc b/src/tint/reader/wgsl/token.cc
index aec1c9a..c6a06c9 100644
--- a/src/tint/reader/wgsl/token.cc
+++ b/src/tint/reader/wgsl/token.cc
@@ -141,6 +141,8 @@
return "break";
case Token::Type::kCase:
return "case";
+ case Token::Type::kConst:
+ return "const";
case Token::Type::kContinue:
return "continue";
case Token::Type::kContinuing:
diff --git a/src/tint/reader/wgsl/token.h b/src/tint/reader/wgsl/token.h
index 2fcf742..df78a5b 100644
--- a/src/tint/reader/wgsl/token.h
+++ b/src/tint/reader/wgsl/token.h
@@ -151,6 +151,8 @@
kBreak,
/// A 'case'
kCase,
+ /// A 'const'
+ kConst,
/// A 'continue'
kContinue,
/// A 'continuing'
@@ -349,7 +351,8 @@
bool IsLiteral() const {
return type_ == Type::kIntLiteral || type_ == Type::kIntLiteral_I ||
type_ == Type::kIntLiteral_U || type_ == Type::kFalse || type_ == Type::kTrue ||
- type_ == Type::kFloatLiteral || type_ == Type::kFloatLiteral_F;
+ type_ == Type::kFloatLiteral || type_ == Type::kFloatLiteral_F ||
+ type_ == Type::kFloatLiteral_H;
}
/// @returns true if token is a 'matNxM'
bool IsMatrix() const {
diff --git a/src/tint/reader/wgsl/token_test.cc b/src/tint/reader/wgsl/token_test.cc
index 93fe834..fd4515f 100644
--- a/src/tint/reader/wgsl/token_test.cc
+++ b/src/tint/reader/wgsl/token_test.cc
@@ -85,6 +85,8 @@
EXPECT_THAT(Token(Token::Type::kFloatLiteral, Source{}, d).to_str(), Not(EndsWith("f")));
EXPECT_THAT(Token(Token::Type::kFloatLiteral_F, Source{}, d).to_str(), StartsWith("123"));
EXPECT_THAT(Token(Token::Type::kFloatLiteral_F, Source{}, d).to_str(), EndsWith("f"));
+ EXPECT_THAT(Token(Token::Type::kFloatLiteral_H, Source{}, d).to_str(), StartsWith("123"));
+ EXPECT_THAT(Token(Token::Type::kFloatLiteral_H, Source{}, d).to_str(), EndsWith("h"));
EXPECT_EQ(Token(Token::Type::kIntLiteral, Source{}, i).to_str(), "123");
EXPECT_EQ(Token(Token::Type::kIntLiteral_I, Source{}, i).to_str(), "123i");
EXPECT_EQ(Token(Token::Type::kIntLiteral_U, Source{}, i).to_str(), "123u");
diff --git a/src/tint/resolver/array_accessor_test.cc b/src/tint/resolver/array_accessor_test.cc
index 535d1ff..be49546 100644
--- a/src/tint/resolver/array_accessor_test.cc
+++ b/src/tint/resolver/array_accessor_test.cc
@@ -16,6 +16,7 @@
#include "gmock/gmock.h"
#include "src/tint/resolver/resolver_test_helper.h"
+#include "src/tint/sem/index_accessor_expression.h"
#include "src/tint/sem/reference.h"
using namespace tint::number_suffixes; // NOLINT
@@ -26,7 +27,7 @@
using ResolverIndexAccessorTest = ResolverTest;
TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_F32) {
- Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 1_f));
WrapInFunction(acc);
@@ -35,22 +36,32 @@
}
TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_Ref) {
- Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
auto* acc = IndexAccessor("my_var", idx);
WrapInFunction(Decl(idx), acc);
EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions_Dynamic_Ref) {
- Global("my_var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
auto* idx = Var("idx", ty.u32(), Expr(3_u));
auto* idy = Var("idy", ty.u32(), Expr(2_u));
auto* acc = IndexAccessor(IndexAccessor("my_var", idx), idy);
WrapInFunction(Decl(idx), Decl(idy), acc);
EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic) {
@@ -61,12 +72,17 @@
EXPECT_TRUE(r()->Resolve());
EXPECT_EQ(r()->error(), "");
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Matrix_XDimension_Dynamic) {
- GlobalConst("my_var", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
+ GlobalConst("my_const", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
auto* idx = Var("idx", ty.u32(), Expr(3_u));
- auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, idx));
+ auto* acc = IndexAccessor("my_const", Expr(Source{{12, 34}}, idx));
WrapInFunction(Decl(idx), acc);
EXPECT_TRUE(r()->Resolve());
@@ -74,9 +90,9 @@
}
TEST_F(ResolverIndexAccessorTest, Matrix_BothDimension_Dynamic) {
- GlobalConst("my_var", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
+ GlobalConst("my_const", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
auto* idx = Var("idy", ty.u32(), Expr(2_u));
- auto* acc = IndexAccessor(IndexAccessor("my_var", Expr(Source{{12, 34}}, idx)), 1_i);
+ auto* acc = IndexAccessor(IndexAccessor("my_const", Expr(Source{{12, 34}}, idx)), 1_i);
WrapInFunction(Decl(idx), acc);
EXPECT_TRUE(r()->Resolve());
@@ -84,7 +100,7 @@
}
TEST_F(ResolverIndexAccessorTest, Matrix) {
- Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
auto* acc = IndexAccessor("my_var", 2_i);
WrapInFunction(acc);
@@ -97,10 +113,15 @@
auto* ref = TypeOf(acc)->As<sem::Reference>();
ASSERT_TRUE(ref->StoreType()->Is<sem::Vector>());
EXPECT_EQ(ref->StoreType()->As<sem::Vector>()->Width(), 3u);
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions) {
- Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
auto* acc = IndexAccessor(IndexAccessor("my_var", 2_i), 1_i);
WrapInFunction(acc);
@@ -112,10 +133,15 @@
auto* ref = TypeOf(acc)->As<sem::Reference>();
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Vector_F32) {
- Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 2_f));
WrapInFunction(acc);
@@ -124,25 +150,30 @@
}
TEST_F(ResolverIndexAccessorTest, Vector_Dynamic_Ref) {
- Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* idx = Var("idx", ty.i32(), Expr(2_i));
auto* acc = IndexAccessor("my_var", idx);
WrapInFunction(Decl(idx), acc);
EXPECT_TRUE(r()->Resolve());
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Vector_Dynamic) {
- GlobalConst("my_var", ty.vec3<f32>(), Construct(ty.vec3<f32>()));
+ GlobalConst("my_const", ty.vec3<f32>(), Construct(ty.vec3<f32>()));
auto* idx = Var("idx", ty.i32(), Expr(2_i));
- auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, idx));
+ auto* acc = IndexAccessor("my_const", Expr(Source{{12, 34}}, idx));
WrapInFunction(Decl(idx), acc);
EXPECT_TRUE(r()->Resolve());
}
TEST_F(ResolverIndexAccessorTest, Vector) {
- Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* acc = IndexAccessor("my_var", 2_i);
WrapInFunction(acc);
@@ -154,10 +185,15 @@
auto* ref = TypeOf(acc)->As<sem::Reference>();
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Array_Literal_i32) {
- Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
auto* acc = IndexAccessor("my_var", 2_i);
WrapInFunction(acc);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -165,10 +201,15 @@
auto* ref = TypeOf(acc)->As<sem::Reference>();
ASSERT_NE(ref, nullptr);
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Array_Literal_u32) {
- Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
auto* acc = IndexAccessor("my_var", 2_u);
WrapInFunction(acc);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -176,10 +217,15 @@
auto* ref = TypeOf(acc)->As<sem::Reference>();
ASSERT_NE(ref, nullptr);
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Array_Literal_AInt) {
- Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
auto* acc = IndexAccessor("my_var", 2_a);
WrapInFunction(acc);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -187,12 +233,17 @@
auto* ref = TypeOf(acc)->As<sem::Reference>();
ASSERT_NE(ref, nullptr);
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Alias_Array) {
auto* aary = Alias("myarrty", ty.array<f32, 3>());
- Global("my_var", ty.Of(aary), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.Of(aary), ast::StorageClass::kPrivate);
auto* acc = IndexAccessor("my_var", 2_i);
WrapInFunction(acc);
@@ -204,12 +255,17 @@
auto* ref = TypeOf(acc)->As<sem::Reference>();
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Array_Constant) {
- GlobalConst("my_var", ty.array<f32, 3>(), array<f32, 3>());
+ GlobalConst("my_const", ty.array<f32, 3>(), array<f32, 3>());
- auto* acc = IndexAccessor("my_var", 2_i);
+ auto* acc = IndexAccessor("my_const", 2_i);
WrapInFunction(acc);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -224,7 +280,8 @@
// var f : f32 = a[idx];
auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
- auto* f = Var("f", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, idx)));
+ auto* acc = IndexAccessor("a", Expr(Source{{12, 34}}, idx));
+ auto* f = Var("f", ty.f32(), acc);
Func("my_func", {}, ty.void_(),
{
Decl(a),
@@ -234,6 +291,11 @@
EXPECT_TRUE(r()->Resolve());
EXPECT_EQ(r()->error(), "");
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Array_Literal_F32) {
@@ -254,13 +316,19 @@
// let a : array<f32, 3>;
// var f : f32 = a[2i];
auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
- auto* f = Var("a_2", ty.f32(), IndexAccessor("a", 2_i));
+ auto* acc = IndexAccessor("a", 2_i);
+ auto* f = Var("a_2", ty.f32(), acc);
Func("my_func", {}, ty.void_(),
{
Decl(a),
Decl(f),
});
EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Expr_Deref_FuncGoodParent) {
@@ -272,11 +340,16 @@
auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction));
auto* idx = Let("idx", ty.u32(), Construct(ty.u32()));
auto* star_p = Deref(p);
- auto* accessor_expr = IndexAccessor(Source{{12, 34}}, star_p, idx);
- auto* x = Var("x", ty.f32(), accessor_expr);
+ auto* acc = IndexAccessor(Source{{12, 34}}, star_p, idx);
+ auto* x = Var("x", ty.f32(), acc);
Func("func", {p}, ty.f32(), {Decl(idx), Decl(x), Return(x)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto idx_sem = Sem().Get(acc);
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
TEST_F(ResolverIndexAccessorTest, Expr_Deref_FuncBadParent) {
diff --git a/src/tint/resolver/assignment_validation_test.cc b/src/tint/resolver/assignment_validation_test.cc
index 6af636e..e204a62 100644
--- a/src/tint/resolver/assignment_validation_test.cc
+++ b/src/tint/resolver/assignment_validation_test.cc
@@ -30,11 +30,11 @@
// @group(0) @binding(0)
// var<storage,read> a : S;
auto* s = Structure("S", {Member("m", ty.i32())});
- Global(Source{{12, 34}}, "a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{12, 34}}, "a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("a", "m"), 1_i));
@@ -61,7 +61,7 @@
}
TEST_F(ResolverAssignmentValidationTest, AssignArraysWithDifferentSizeExpressions_Pass) {
- // let len = 4u;
+ // const len = 4u;
// {
// var a : array<f32, 4u>;
// var b : array<f32, len>;
@@ -80,7 +80,7 @@
}
TEST_F(ResolverAssignmentValidationTest, AssignArraysWithDifferentSizeExpressions_Fail) {
- // let len = 5u;
+ // const len = 5u;
// {
// var a : array<f32, 4u>;
// var b : array<f32, len>;
@@ -235,16 +235,16 @@
ast::Access::kWrite);
};
- Global("a", make_type(), ast::StorageClass::kNone,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
- Global("b", make_type(), ast::StorageClass::kNone,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("a", make_type(), ast::StorageClass::kNone,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
+ GlobalVar("b", make_type(), ast::StorageClass::kNone,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(0u),
+ });
WrapInFunction(Assign(Source{{56, 78}}, "a", "b"));
@@ -258,11 +258,11 @@
// v.a = v.a;
auto* s = Structure("S", {Member("a", ty.atomic(ty.i32()))});
- Global(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("v", "a"), MemberAccessor("v", "a")));
@@ -276,11 +276,11 @@
// v.a = v.a;
auto* s = Structure("S", {Member("a", ty.array(ty.f32()))});
- Global(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("v", "a"), MemberAccessor("v", "a")));
@@ -297,7 +297,7 @@
// _ = s;
// }
auto* s = Structure("S", {Member("arr", ty.array<i32>())});
- Global("s", ty.Of(s), ast::StorageClass::kStorage, GroupAndBinding(0, 0));
+ GlobalVar("s", ty.Of(s), ast::StorageClass::kStorage, GroupAndBinding(0, 0));
WrapInFunction(Assign(Phony(), Expr(Source{{12, 34}}, "s")));
@@ -317,7 +317,7 @@
// _ = s.arr;
// }
auto* s = Structure("S", {Member("arr", ty.array<i32>())});
- Global("s", ty.Of(s), ast::StorageClass::kStorage, GroupAndBinding(0, 0));
+ GlobalVar("s", ty.Of(s), ast::StorageClass::kStorage, GroupAndBinding(0, 0));
WrapInFunction(Assign(Phony(), MemberAccessor(Source{{12, 34}}, "s", "arr")));
@@ -365,11 +365,12 @@
Member("arr", ty.array<i32>()),
});
auto* U = Structure("U", {Member("i", ty.i32())});
- Global("tex", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(0, 0));
- Global("smp", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(0, 1));
- Global("u", ty.Of(U), ast::StorageClass::kUniform, GroupAndBinding(0, 2));
- Global("s", ty.Of(S), ast::StorageClass::kStorage, GroupAndBinding(0, 3));
- Global("wg", ty.array<f32, 10>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("tex", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ GroupAndBinding(0, 0));
+ GlobalVar("smp", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(0, 1));
+ GlobalVar("u", ty.Of(U), ast::StorageClass::kUniform, GroupAndBinding(0, 2));
+ GlobalVar("s", ty.Of(S), ast::StorageClass::kStorage, GroupAndBinding(0, 3));
+ GlobalVar("wg", ty.array<f32, 10>(), ast::StorageClass::kWorkgroup);
WrapInFunction(Assign(Phony(), 1_i), //
Assign(Phony(), 2_u), //
diff --git a/src/tint/resolver/atomics_test.cc b/src/tint/resolver/atomics_test.cc
index c0fe5ce..09ca0ba 100644
--- a/src/tint/resolver/atomics_test.cc
+++ b/src/tint/resolver/atomics_test.cc
@@ -25,7 +25,7 @@
struct ResolverAtomicTest : public resolver::TestHelper, public testing::Test {};
TEST_F(ResolverAtomicTest, GlobalWorkgroupI32) {
- auto* g = Global("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kWorkgroup);
+ auto* g = GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kWorkgroup);
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_TRUE(TypeOf(g)->Is<sem::Reference>());
@@ -35,7 +35,7 @@
}
TEST_F(ResolverAtomicTest, GlobalWorkgroupU32) {
- auto* g = Global("a", ty.atomic(Source{{12, 34}}, ty.u32()), ast::StorageClass::kWorkgroup);
+ auto* g = GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.u32()), ast::StorageClass::kWorkgroup);
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_TRUE(TypeOf(g)->Is<sem::Reference>());
@@ -46,11 +46,11 @@
TEST_F(ResolverAtomicTest, GlobalStorageStruct) {
auto* s = Structure("s", {Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
- auto* g = Global("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* g = GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
ASSERT_TRUE(TypeOf(g)->Is<sem::Reference>());
diff --git a/src/tint/resolver/atomics_validation_test.cc b/src/tint/resolver/atomics_validation_test.cc
index 78c1fb9..5ec4e01 100644
--- a/src/tint/resolver/atomics_validation_test.cc
+++ b/src/tint/resolver/atomics_validation_test.cc
@@ -27,35 +27,35 @@
struct ResolverAtomicValidationTest : public resolver::TestHelper, public testing::Test {};
TEST_F(ResolverAtomicValidationTest, StorageClass_WorkGroup) {
- Global("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kWorkgroup);
+ GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kWorkgroup);
EXPECT_TRUE(r()->Resolve());
}
TEST_F(ResolverAtomicValidationTest, StorageClass_Storage) {
- Global("g", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kStorage,
- ast::Access::kReadWrite, GroupAndBinding(0, 0));
+ GlobalVar("g", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kStorage,
+ ast::Access::kReadWrite, GroupAndBinding(0, 0));
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverAtomicValidationTest, StorageClass_Storage_Struct) {
auto* s = Structure("s", {Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
- Global("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- GroupAndBinding(0, 0));
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ GroupAndBinding(0, 0));
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverAtomicValidationTest, InvalidType) {
- Global("a", ty.atomic(ty.f32(Source{{12, 34}})), ast::StorageClass::kWorkgroup);
+ GlobalVar("a", ty.atomic(ty.f32(Source{{12, 34}})), ast::StorageClass::kWorkgroup);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: atomic only supports i32 or u32 types");
}
TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_Simple) {
- Global("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -64,7 +64,7 @@
}
TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_Array) {
- Global("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -74,7 +74,7 @@
TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_Struct) {
auto* s = Structure("s", {Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
- Global("g", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -90,7 +90,7 @@
auto* Inner = Structure("Inner", {Member("m", ty.atomic(Source{{12, 34}}, ty.i32()))});
auto* Outer = Structure("Outer", {Member("m", ty.Of(Inner))});
- Global("g", ty.Of(Outer), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(Outer), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -106,7 +106,7 @@
auto* Inner = Structure("Inner", {Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
auto* Outer = Structure("Outer", {Member("m", ty.Of(Inner))});
- Global("g", ty.Of(Outer), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(Outer), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -121,7 +121,7 @@
auto* atomic_array =
Alias(Source{{12, 34}}, "AtomicArray", ty.atomic(Source{{12, 34}}, ty.i32()));
- Global(Source{{56, 78}}, "v", ty.Of(atomic_array), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{56, 78}}, "v", ty.Of(atomic_array), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -136,7 +136,7 @@
// var<private> v: array<S, 5u>;
auto* s = Structure("S", {Member("m", ty.atomic<u32>())});
- Global(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -155,7 +155,7 @@
auto* atomic_array =
Alias(Source{{12, 34}}, "AtomicArray", ty.atomic(Source{{12, 34}}, ty.i32()));
auto* s = Structure("S", {Member("m", ty.Of(atomic_array))});
- Global(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -196,7 +196,7 @@
auto* s2 = Structure("S2", {Member("x", ty.Of(s3))});
auto* s1 = Structure("S1", {Member("x", ty.Of(s2))});
auto* s0 = Structure("S0", {Member("x", ty.Of(s1))});
- Global(Source{{56, 78}}, "g", ty.Of(s0), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(s0), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -207,8 +207,8 @@
TEST_F(ResolverAtomicValidationTest, Struct_AccessMode_Read) {
auto* s = Structure("s", {Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
- Global(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ GroupAndBinding(0, 0));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -219,8 +219,8 @@
TEST_F(ResolverAtomicValidationTest, InvalidAccessMode_Struct) {
auto* s = Structure("s", {Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
- Global(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ GroupAndBinding(0, 0));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -236,8 +236,8 @@
auto* Inner = Structure("Inner", {Member("m", ty.atomic(Source{{12, 34}}, ty.i32()))});
auto* Outer = Structure("Outer", {Member("m", ty.Of(Inner))});
- Global(Source{{56, 78}}, "g", ty.Of(Outer), ast::StorageClass::kStorage, ast::Access::kRead,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::StorageClass::kStorage, ast::Access::kRead,
+ GroupAndBinding(0, 0));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -253,8 +253,8 @@
auto* Inner = Structure("Inner", {Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
auto* Outer = Structure("Outer", {Member("m", ty.Of(Inner))});
- Global(Source{{56, 78}}, "g", ty.Of(Outer), ast::StorageClass::kStorage, ast::Access::kRead,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::StorageClass::kStorage, ast::Access::kRead,
+ GroupAndBinding(0, 0));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -295,8 +295,8 @@
auto* s2 = Structure("S2", {Member("x", ty.Of(s3))});
auto* s1 = Structure("S1", {Member("x", ty.Of(s2))});
auto* s0 = Structure("S0", {Member("x", ty.Of(s1))});
- Global(Source{{56, 78}}, "g", ty.Of(s0), ast::StorageClass::kStorage, ast::Access::kRead,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(s0), ast::StorageClass::kStorage, ast::Access::kRead,
+ GroupAndBinding(0, 0));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -309,7 +309,7 @@
WrapInFunction(Var("a", ty.atomic(Source{{12, 34}}, ty.i32())));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: function variable must have a constructible type");
+ EXPECT_EQ(r()->error(), "12:34 error: function-scope 'var' must have a constructible type");
}
} // namespace
diff --git a/src/tint/resolver/attribute_validation_test.cc b/src/tint/resolver/attribute_validation_test.cc
index f7e401b..5f69277 100644
--- a/src/tint/resolver/attribute_validation_test.cc
+++ b/src/tint/resolver/attribute_validation_test.cc
@@ -508,8 +508,8 @@
TEST_F(EntryPointParameterAttributeTest, DuplicateInternalAttribute) {
auto* s = Param("s", ty.sampler(ast::SamplerKind::kSampler),
ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
Disable(ast::DisabledValidation::kBindingPointCollision),
Disable(ast::DisabledValidation::kEntryPointParameter),
});
@@ -707,11 +707,11 @@
auto& params = GetParam();
if (IsBindingAttribute(params.kind)) {
- Global("a", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone, nullptr,
- createAttributes(Source{{12, 34}}, *this, params.kind));
+ GlobalVar("a", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone, nullptr,
+ createAttributes(Source{{12, 34}}, *this, params.kind));
} else {
- Global("a", ty.f32(), ast::StorageClass::kPrivate, nullptr,
- createAttributes(Source{{12, 34}}, *this, params.kind));
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate, nullptr,
+ createAttributes(Source{{12, 34}}, *this, params.kind));
}
WrapInFunction();
@@ -743,12 +743,12 @@
TestParams{AttributeKind::kBindingAndGroup, true}));
TEST_F(VariableAttributeTest, DuplicateAttribute) {
- Global("a", ty.sampler(ast::SamplerKind::kSampler),
- ast::AttributeList{
- create<ast::BindingAttribute>(Source{{12, 34}}, 2),
- create<ast::GroupAttribute>(2),
- create<ast::BindingAttribute>(Source{{56, 78}}, 3),
- });
+ GlobalVar("a", ty.sampler(ast::SamplerKind::kSampler),
+ ast::AttributeList{
+ create<ast::BindingAttribute>(Source{{12, 34}}, 2u),
+ create<ast::GroupAttribute>(2u),
+ create<ast::BindingAttribute>(Source{{56, 78}}, 3u),
+ });
WrapInFunction();
@@ -761,7 +761,7 @@
TEST_F(VariableAttributeTest, LocalVariable) {
auto* v = Var("a", ty.f32(),
ast::AttributeList{
- create<ast::BindingAttribute>(Source{{12, 34}}, 2),
+ create<ast::BindingAttribute>(Source{{12, 34}}, 2u),
});
WrapInFunction(v);
@@ -784,7 +784,7 @@
} else {
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: attribute is not valid for module-scope 'let' declaration");
+ "12:34 error: attribute is not valid for module-scope 'const' declaration");
}
}
INSTANTIATE_TEST_SUITE_P(ResolverAttributeValidationTest,
@@ -807,8 +807,8 @@
TEST_F(ConstantAttributeTest, DuplicateAttribute) {
GlobalConst("a", ty.f32(), Expr(1.23_f),
ast::AttributeList{
- create<ast::IdAttribute>(Source{{12, 34}}, 0),
- create<ast::IdAttribute>(Source{{56, 78}}, 1),
+ create<ast::IdAttribute>(Source{{12, 34}}, 0u),
+ create<ast::IdAttribute>(Source{{56, 78}}, 1u),
});
WrapInFunction();
@@ -852,11 +852,11 @@
TestParams{AttributeKind::kBindingAndGroup, false}));
TEST_F(OverrideAttributeTest, DuplicateAttribute) {
- GlobalConst("a", ty.f32(), Expr(1.23_f),
- ast::AttributeList{
- create<ast::IdAttribute>(Source{{12, 34}}, 0),
- create<ast::IdAttribute>(Source{{56, 78}}, 1),
- });
+ Override("a", ty.f32(), Expr(1.23_f),
+ ast::AttributeList{
+ create<ast::IdAttribute>(Source{{12, 34}}, 0u),
+ create<ast::IdAttribute>(Source{{56, 78}}, 1u),
+ });
WrapInFunction();
@@ -897,7 +897,7 @@
auto* arr = ty.array(Source{{12, 34}}, el_ty, 4_u, params.stride);
- Global("myarray", arr, ast::StorageClass::kPrivate);
+ GlobalVar("myarray", arr, ast::StorageClass::kPrivate);
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -976,11 +976,11 @@
TEST_F(ArrayStrideTest, DuplicateAttribute) {
auto* arr = ty.array(Source{{12, 34}}, ty.i32(), 4_u,
{
- create<ast::StrideAttribute>(Source{{12, 34}}, 4_i),
- create<ast::StrideAttribute>(Source{{56, 78}}, 4_i),
+ create<ast::StrideAttribute>(Source{{12, 34}}, 4u),
+ create<ast::StrideAttribute>(Source{{56, 78}}, 4u),
});
- Global("myarray", arr, ast::StorageClass::kPrivate);
+ GlobalVar("myarray", arr, ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -997,7 +997,7 @@
using ResourceAttributeTest = ResolverTest;
TEST_F(ResourceAttributeTest, UniformBufferMissingBinding) {
auto* s = Structure("S", {Member("x", ty.i32())});
- Global(Source{{12, 34}}, "G", ty.Of(s), ast::StorageClass::kUniform);
+ GlobalVar(Source{{12, 34}}, "G", ty.Of(s), ast::StorageClass::kUniform);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1006,7 +1006,7 @@
TEST_F(ResourceAttributeTest, StorageBufferMissingBinding) {
auto* s = Structure("S", {Member("x", ty.i32())});
- Global(Source{{12, 34}}, "G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead);
+ GlobalVar(Source{{12, 34}}, "G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1014,8 +1014,8 @@
}
TEST_F(ResourceAttributeTest, TextureMissingBinding) {
- Global(Source{{12, 34}}, "G", ty.depth_texture(ast::TextureDimension::k2d),
- ast::StorageClass::kNone);
+ GlobalVar(Source{{12, 34}}, "G", ty.depth_texture(ast::TextureDimension::k2d),
+ ast::StorageClass::kNone);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1023,7 +1023,8 @@
}
TEST_F(ResourceAttributeTest, SamplerMissingBinding) {
- Global(Source{{12, 34}}, "G", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone);
+ GlobalVar(Source{{12, 34}}, "G", ty.sampler(ast::SamplerKind::kSampler),
+ ast::StorageClass::kNone);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1031,10 +1032,11 @@
}
TEST_F(ResourceAttributeTest, BindingPairMissingBinding) {
- Global(Source{{12, 34}}, "G", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone,
- ast::AttributeList{
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar(Source{{12, 34}}, "G", ty.sampler(ast::SamplerKind::kSampler),
+ ast::StorageClass::kNone,
+ ast::AttributeList{
+ create<ast::GroupAttribute>(1u),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1042,10 +1044,11 @@
}
TEST_F(ResourceAttributeTest, BindingPairMissingGroup) {
- Global(Source{{12, 34}}, "G", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- });
+ GlobalVar(Source{{12, 34}}, "G", ty.sampler(ast::SamplerKind::kSampler),
+ ast::StorageClass::kNone,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -1053,18 +1056,18 @@
}
TEST_F(ResourceAttributeTest, BindingPointUsedTwiceByEntryPoint) {
- Global(Source{{12, 34}}, "A", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
- ast::StorageClass::kNone,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
- Global(Source{{56, 78}}, "B", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
- ast::StorageClass::kNone,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar(Source{{12, 34}}, "A", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ ast::StorageClass::kNone,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
+ GlobalVar(Source{{56, 78}}, "B", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ ast::StorageClass::kNone,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("F", {}, ty.void_(),
{
@@ -1085,18 +1088,18 @@
}
TEST_F(ResourceAttributeTest, BindingPointUsedTwiceByDifferentEntryPoints) {
- Global(Source{{12, 34}}, "A", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
- ast::StorageClass::kNone,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
- Global(Source{{56, 78}}, "B", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
- ast::StorageClass::kNone,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar(Source{{12, 34}}, "A", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ ast::StorageClass::kNone,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
+ GlobalVar(Source{{56, 78}}, "B", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ ast::StorageClass::kNone,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("F_A", {}, ty.void_(),
{
@@ -1119,11 +1122,11 @@
}
TEST_F(ResourceAttributeTest, BindingPointOnNonResource) {
- Global(Source{{12, 34}}, "G", ty.f32(), ast::StorageClass::kPrivate,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar(Source{{12, 34}}, "G", ty.f32(), ast::StorageClass::kPrivate,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
diff --git a/src/tint/resolver/builtin_test.cc b/src/tint/resolver/builtin_test.cc
index ef9f1bd..38f5620 100644
--- a/src/tint/resolver/builtin_test.cc
+++ b/src/tint/resolver/builtin_test.cc
@@ -52,7 +52,7 @@
TEST_P(ResolverBuiltinDerivativeTest, Scalar) {
auto name = GetParam();
- Global("ident", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("ident", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call(name, "ident");
Func("func", {}, ty.void_(), {Ignore(expr)},
@@ -66,7 +66,7 @@
TEST_P(ResolverBuiltinDerivativeTest, Vector) {
auto name = GetParam();
- Global("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call(name, "ident");
Func("func", {}, ty.void_(), {Ignore(expr)},
@@ -110,7 +110,7 @@
TEST_P(ResolverBuiltinTest_BoolMethod, Scalar) {
auto name = GetParam();
- Global("my_var", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = Call(name, "my_var");
WrapInFunction(expr);
@@ -123,7 +123,7 @@
TEST_P(ResolverBuiltinTest_BoolMethod, Vector) {
auto name = GetParam();
- Global("my_var", ty.vec3<bool>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.vec3<bool>(), ast::StorageClass::kPrivate);
auto* expr = Call(name, "my_var");
WrapInFunction(expr);
@@ -185,14 +185,14 @@
void add_call_param(std::string name, const ast::Type* type, ast::ExpressionList* call_params) {
if (type->IsAnyOf<ast::Texture, ast::Sampler>()) {
- Global(name, type,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(name, type,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
} else {
- Global(name, type, ast::StorageClass::kPrivate);
+ GlobalVar(name, type, ast::StorageClass::kPrivate);
}
call_params->push_back(Expr(name));
@@ -251,7 +251,7 @@
TextureTestParams{ast::TextureDimension::k3d}));
TEST_F(ResolverBuiltinTest, Dot_Vec2) {
- Global("my_var", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.vec2<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "my_var", "my_var");
WrapInFunction(expr);
@@ -263,7 +263,7 @@
}
TEST_F(ResolverBuiltinTest, Dot_Vec3) {
- Global("my_var", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.vec3<i32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "my_var", "my_var");
WrapInFunction(expr);
@@ -275,7 +275,7 @@
}
TEST_F(ResolverBuiltinTest, Dot_Vec4) {
- Global("my_var", ty.vec4<u32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.vec4<u32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "my_var", "my_var");
WrapInFunction(expr);
@@ -301,9 +301,9 @@
}
TEST_F(ResolverBuiltinTest, Select) {
- Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
- Global("bool_var", ty.vec3<bool>(), ast::StorageClass::kPrivate);
+ GlobalVar("bool_var", ty.vec3<bool>(), ast::StorageClass::kPrivate);
auto* expr = Call("select", "my_var", "my_var", "bool_var");
WrapInFunction(expr);
@@ -616,11 +616,11 @@
TEST_F(ResolverBuiltinDataTest, ArrayLength_Vector) {
auto* ary = ty.array<i32>();
auto* str = Structure("S", {Member("x", ary)});
- Global("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
auto* call = Call("arrayLength", AddressOf(MemberAccessor("a", "x")));
WrapInFunction(call);
@@ -632,7 +632,7 @@
}
TEST_F(ResolverBuiltinDataTest, ArrayLength_Error_ArraySized) {
- Global("arr", ty.array<i32, 4>(), ast::StorageClass::kPrivate);
+ GlobalVar("arr", ty.array<i32, 4>(), ast::StorageClass::kPrivate);
auto* call = Call("arrayLength", AddressOf("arr"));
WrapInFunction(call);
@@ -733,7 +733,7 @@
}
TEST_F(ResolverBuiltinDataTest, Frexp_Error_FirstParamInt) {
- Global("v", ty.i32(), ast::StorageClass::kWorkgroup);
+ GlobalVar("v", ty.i32(), ast::StorageClass::kWorkgroup);
auto* call = Call("frexp", 1_i, AddressOf("v"));
WrapInFunction(call);
@@ -749,7 +749,7 @@
}
TEST_F(ResolverBuiltinDataTest, Frexp_Error_SecondParamFloatPtr) {
- Global("v", ty.f32(), ast::StorageClass::kWorkgroup);
+ GlobalVar("v", ty.f32(), ast::StorageClass::kWorkgroup);
auto* call = Call("frexp", 1_f, AddressOf("v"));
WrapInFunction(call);
@@ -779,7 +779,7 @@
}
TEST_F(ResolverBuiltinDataTest, Frexp_Error_VectorSizesDontMatch) {
- Global("v", ty.vec4<i32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("v", ty.vec4<i32>(), ast::StorageClass::kWorkgroup);
auto* call = Call("frexp", vec2<f32>(1_f, 2_f), AddressOf("v"));
WrapInFunction(call);
@@ -857,7 +857,7 @@
}
TEST_F(ResolverBuiltinDataTest, Modf_Error_FirstParamInt) {
- Global("whole", ty.f32(), ast::StorageClass::kWorkgroup);
+ GlobalVar("whole", ty.f32(), ast::StorageClass::kWorkgroup);
auto* call = Call("modf", 1_i, AddressOf("whole"));
WrapInFunction(call);
@@ -873,7 +873,7 @@
}
TEST_F(ResolverBuiltinDataTest, Modf_Error_SecondParamIntPtr) {
- Global("whole", ty.i32(), ast::StorageClass::kWorkgroup);
+ GlobalVar("whole", ty.i32(), ast::StorageClass::kWorkgroup);
auto* call = Call("modf", 1_f, AddressOf("whole"));
WrapInFunction(call);
@@ -903,7 +903,7 @@
}
TEST_F(ResolverBuiltinDataTest, Modf_Error_VectorSizesDontMatch) {
- Global("whole", ty.vec4<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("whole", ty.vec4<f32>(), ast::StorageClass::kWorkgroup);
auto* call = Call("modf", vec2<f32>(1_f, 2_f), AddressOf("whole"));
WrapInFunction(call);
@@ -1512,7 +1512,7 @@
BuiltinData{"max", BuiltinType::kMax}));
TEST_F(ResolverBuiltinTest, Determinant_2x2) {
- Global("var", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("var", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
auto* call = Call("determinant", "var");
WrapInFunction(call);
@@ -1524,7 +1524,7 @@
}
TEST_F(ResolverBuiltinTest, Determinant_3x3) {
- Global("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* call = Call("determinant", "var");
WrapInFunction(call);
@@ -1536,7 +1536,7 @@
}
TEST_F(ResolverBuiltinTest, Determinant_4x4) {
- Global("var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
auto* call = Call("determinant", "var");
WrapInFunction(call);
@@ -1548,7 +1548,7 @@
}
TEST_F(ResolverBuiltinTest, Determinant_NotSquare) {
- Global("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
auto* call = Call("determinant", "var");
WrapInFunction(call);
@@ -1563,7 +1563,7 @@
}
TEST_F(ResolverBuiltinTest, Determinant_NotMatrix) {
- Global("var", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
auto* call = Call("determinant", "var");
WrapInFunction(call);
diff --git a/src/tint/resolver/builtin_validation_test.cc b/src/tint/resolver/builtin_validation_test.cc
index d82c2f3..3737ae0 100644
--- a/src/tint/resolver/builtin_validation_test.cc
+++ b/src/tint/resolver/builtin_validation_test.cc
@@ -85,20 +85,21 @@
R"(12:34 error: 'mix' is a builtin and cannot be redeclared as a function)");
}
-TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalLet) {
+TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalConst) {
GlobalConst(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: 'mix' is a builtin and cannot be redeclared as a module-scope let)");
+ R"(12:34 error: 'mix' is a builtin and cannot be redeclared as a 'const')");
}
TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalVar) {
- Global(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- R"(12:34 error: 'mix' is a builtin and cannot be redeclared as a module-scope var)");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: 'mix' is a builtin and cannot be redeclared as a module-scope 'var')");
}
TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsAlias) {
@@ -256,11 +257,11 @@
err << "12:34 error: each component of the " << param.name
<< " argument must be at least " << param.min << " and at most " << param.max
<< ". " << param.name << " component " << expr.invalid_index << " is "
- << std::to_string(expr.values[expr.invalid_index]);
+ << std::to_string(expr.values[static_cast<size_t>(expr.invalid_index)]);
} else {
err << "12:34 error: the " << param.name << " argument must be at least " << param.min
<< " and at most " << param.max << ". " << param.name << " is "
- << std::to_string(expr.values[expr.invalid_index]);
+ << std::to_string(expr.values[static_cast<size_t>(expr.invalid_index)]);
}
EXPECT_EQ(r()->error(), err.str());
}
@@ -276,7 +277,7 @@
overload.BuildTextureVariable(this);
overload.BuildSamplerVariable(this);
- // Build the module-scope let 'G' with the offset value
+ // Build the module-scope const 'G' with the offset value
GlobalConst("G", nullptr, expr({}, *this));
auto args = overload.args(this);
@@ -297,7 +298,6 @@
err << "12:34 error: the " << param.name << " argument must be a const_expression";
EXPECT_EQ(r()->error(), err.str());
}
-
INSTANTIATE_TEST_SUITE_P(
Offset2D,
BuiltinTextureConstExprArgValidationTest,
diff --git a/src/tint/resolver/builtins_validation_test.cc b/src/tint/resolver/builtins_validation_test.cc
index 6f0cf85..15fd2b6 100644
--- a/src/tint/resolver/builtins_validation_test.cc
+++ b/src/tint/resolver/builtins_validation_test.cc
@@ -92,7 +92,7 @@
TEST_P(ResolverBuiltinsStageTest, All_input) {
const Params& params = GetParam();
- auto* p = Global("p", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ auto* p = GlobalVar("p", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* input = Param("input", params.type(*this), {Builtin(Source{{12, 34}}, params.builtin)});
switch (params.stage) {
case ast::PipelineStage::kVertex:
diff --git a/src/tint/resolver/call_test.cc b/src/tint/resolver/call_test.cc
index 5351623..3020254 100644
--- a/src/tint/resolver/call_test.cc
+++ b/src/tint/resolver/call_test.cc
@@ -71,6 +71,7 @@
ParamsFor<u32>(), //
ParamsFor<i32>(), //
ParamsFor<f32>(), //
+ ParamsFor<f16>(), //
ParamsFor<vec3<bool>>(), //
ParamsFor<vec3<i32>>(), //
ParamsFor<vec3<u32>>(), //
@@ -81,6 +82,8 @@
};
TEST_F(ResolverCallTest, Valid) {
+ Enable(ast::Extension::kF16);
+
ast::ParameterList params;
ast::ExpressionList args;
for (auto& p : all_param_types) {
diff --git a/src/tint/resolver/call_validation_test.cc b/src/tint/resolver/call_validation_test.cc
index 850e2c6..9625be7 100644
--- a/src/tint/resolver/call_validation_test.cc
+++ b/src/tint/resolver/call_validation_test.cc
@@ -219,7 +219,7 @@
// var c: i32 = foo(p);
// }
Func("foo", {Param("p", ty.pointer<i32>(ast::StorageClass::kPrivate))}, ty.void_(), {});
- auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* p = Let("p", ty.pointer(ty.i32(), ast::StorageClass::kPrivate), AddressOf(v));
auto* c = Var("c", ty.i32(), ast::StorageClass::kNone, Call("foo", Expr(Source{{12, 34}}, p)));
Func("main", {}, ty.void_(),
@@ -241,7 +241,7 @@
// fn f() {
// v();
// }
- Global("v", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
Func("f", {}, ty.void_(), {CallStmt(Call(Source{{12, 34}}, "v"))});
EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/compound_assignment_validation_test.cc b/src/tint/resolver/compound_assignment_validation_test.cc
index b453c3b..5edcdaa 100644
--- a/src/tint/resolver/compound_assignment_validation_test.cc
+++ b/src/tint/resolver/compound_assignment_validation_test.cc
@@ -233,8 +233,8 @@
// {
// a += 1i;
// }
- Global(Source{{12, 34}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
+ GroupAndBinding(0, 0));
WrapInFunction(CompoundAssign(Source{{56, 78}}, "a", 1_i, ast::BinaryOp::kAdd));
EXPECT_FALSE(r()->Resolve());
@@ -264,7 +264,7 @@
TEST_F(ResolverCompoundAssignmentValidationTest, LhsAtomic) {
// var<workgroup> a : atomic<i32>;
// a += a;
- Global(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::StorageClass::kWorkgroup);
+ GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::StorageClass::kWorkgroup);
WrapInFunction(CompoundAssign(Source{{56, 78}}, "a", "a", ast::BinaryOp::kAdd));
EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/const_eval.h b/src/tint/resolver/const_eval.h
index 89bb3da..3792e35 100644
--- a/src/tint/resolver/const_eval.h
+++ b/src/tint/resolver/const_eval.h
@@ -30,7 +30,9 @@
namespace tint::resolver::const_eval {
/// Typedef for a constant evaluation function
-using Function = sem::Constant(ProgramBuilder& builder, const sem::Constant* args, size_t num_args);
+using Function = const sem::Constant*(ProgramBuilder& builder,
+ sem::Constant const* const* args,
+ size_t num_args);
} // namespace tint::resolver::const_eval
diff --git a/src/tint/resolver/ctor_conv_intrinsic.cc b/src/tint/resolver/ctor_conv_intrinsic.cc
index 5618fba..59eb1c5 100644
--- a/src/tint/resolver/ctor_conv_intrinsic.cc
+++ b/src/tint/resolver/ctor_conv_intrinsic.cc
@@ -36,6 +36,8 @@
return "u32";
case CtorConvIntrinsic::kF32:
return "f32";
+ case CtorConvIntrinsic::kF16:
+ return "f16";
case CtorConvIntrinsic::kBool:
return "bool";
case CtorConvIntrinsic::kVec2:
@@ -67,4 +69,3 @@
}
} // namespace tint::resolver
-
diff --git a/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl b/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl
index ac98c4d..db567ca 100644
--- a/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl
+++ b/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl
@@ -25,4 +25,3 @@
}
} // namespace tint::resolver
-
diff --git a/src/tint/resolver/ctor_conv_intrinsic.h b/src/tint/resolver/ctor_conv_intrinsic.h
index 7c68658..186cef7 100644
--- a/src/tint/resolver/ctor_conv_intrinsic.h
+++ b/src/tint/resolver/ctor_conv_intrinsic.h
@@ -36,6 +36,7 @@
kI32,
kU32,
kF32,
+ kF16,
kBool,
kVec2,
kVec3,
diff --git a/src/tint/resolver/dependency_graph.cc b/src/tint/resolver/dependency_graph.cc
index 6b3b779..3d550ff 100644
--- a/src/tint/resolver/dependency_graph.cc
+++ b/src/tint/resolver/dependency_graph.cc
@@ -19,12 +19,58 @@
#include <utility>
#include <vector>
+#include "src/tint/ast/alias.h"
+#include "src/tint/ast/array.h"
+#include "src/tint/ast/assignment_statement.h"
+#include "src/tint/ast/atomic.h"
+#include "src/tint/ast/block_statement.h"
+#include "src/tint/ast/bool.h"
+#include "src/tint/ast/break_statement.h"
+#include "src/tint/ast/call_statement.h"
+#include "src/tint/ast/compound_assignment_statement.h"
#include "src/tint/ast/continue_statement.h"
+#include "src/tint/ast/depth_multisampled_texture.h"
+#include "src/tint/ast/depth_texture.h"
#include "src/tint/ast/discard_statement.h"
+#include "src/tint/ast/external_texture.h"
+#include "src/tint/ast/f16.h"
+#include "src/tint/ast/f32.h"
#include "src/tint/ast/fallthrough_statement.h"
+#include "src/tint/ast/for_loop_statement.h"
+#include "src/tint/ast/i32.h"
+#include "src/tint/ast/id_attribute.h"
+#include "src/tint/ast/if_statement.h"
+#include "src/tint/ast/increment_decrement_statement.h"
+#include "src/tint/ast/internal_attribute.h"
+#include "src/tint/ast/interpolate_attribute.h"
+#include "src/tint/ast/invariant_attribute.h"
+#include "src/tint/ast/location_attribute.h"
+#include "src/tint/ast/loop_statement.h"
+#include "src/tint/ast/matrix.h"
+#include "src/tint/ast/multisampled_texture.h"
+#include "src/tint/ast/pointer.h"
+#include "src/tint/ast/return_statement.h"
+#include "src/tint/ast/sampled_texture.h"
+#include "src/tint/ast/stage_attribute.h"
+#include "src/tint/ast/storage_texture.h"
+#include "src/tint/ast/stride_attribute.h"
+#include "src/tint/ast/struct.h"
+#include "src/tint/ast/struct_member_align_attribute.h"
+#include "src/tint/ast/struct_member_offset_attribute.h"
+#include "src/tint/ast/struct_member_size_attribute.h"
+#include "src/tint/ast/switch_statement.h"
#include "src/tint/ast/traverse_expressions.h"
+#include "src/tint/ast/type_name.h"
+#include "src/tint/ast/u32.h"
+#include "src/tint/ast/variable_decl_statement.h"
+#include "src/tint/ast/vector.h"
+#include "src/tint/ast/void.h"
+#include "src/tint/ast/while_statement.h"
+#include "src/tint/ast/workgroup_attribute.h"
#include "src/tint/scope_stack.h"
#include "src/tint/sem/builtin.h"
+#include "src/tint/symbol_table.h"
+#include "src/tint/utils/block_allocator.h"
#include "src/tint/utils/defer.h"
#include "src/tint/utils/map.h"
#include "src/tint/utils/scoped_assignment.h"
@@ -487,13 +533,11 @@
/// declaration
std::string KindOf(const ast::Node* node) {
return Switch(
- node, //
- [&](const ast::Struct*) { return "struct"; }, //
- [&](const ast::Alias*) { return "alias"; }, //
- [&](const ast::Function*) { return "function"; }, //
- [&](const ast::Let*) { return "let"; }, //
- [&](const ast::Var*) { return "var"; }, //
- [&](const ast::Override*) { return "override"; }, //
+ node, //
+ [&](const ast::Struct*) { return "struct"; }, //
+ [&](const ast::Alias*) { return "alias"; }, //
+ [&](const ast::Function*) { return "function"; }, //
+ [&](const ast::Variable* v) { return v->Kind(); }, //
[&](Default) {
UnhandledNode(diagnostics_, node);
return "<error>";
diff --git a/src/tint/resolver/dependency_graph_test.cc b/src/tint/resolver/dependency_graph_test.cc
index 1117a4a..b7ffa79 100644
--- a/src/tint/resolver/dependency_graph_test.cc
+++ b/src/tint/resolver/dependency_graph_test.cc
@@ -113,12 +113,12 @@
GlobalVarSampledTexElemType,
GlobalVarMultisampledTexElemType,
GlobalVarValue,
- GlobalLetType,
- GlobalLetArrayElemType,
- GlobalLetArraySizeValue,
- GlobalLetVectorElemType,
- GlobalLetMatrixElemType,
- GlobalLetValue,
+ GlobalConstType,
+ GlobalConstArrayElemType,
+ GlobalConstArraySizeValue,
+ GlobalConstVectorElemType,
+ GlobalConstMatrixElemType,
+ GlobalConstValue,
AliasType,
StructMemberType,
CallFunction,
@@ -146,11 +146,11 @@
SymbolUseKind::GlobalVarMatrixElemType,
SymbolUseKind::GlobalVarSampledTexElemType,
SymbolUseKind::GlobalVarMultisampledTexElemType,
- SymbolUseKind::GlobalLetType,
- SymbolUseKind::GlobalLetArrayElemType,
- SymbolUseKind::GlobalLetArraySizeValue,
- SymbolUseKind::GlobalLetVectorElemType,
- SymbolUseKind::GlobalLetMatrixElemType,
+ SymbolUseKind::GlobalConstType,
+ SymbolUseKind::GlobalConstArrayElemType,
+ SymbolUseKind::GlobalConstArraySizeValue,
+ SymbolUseKind::GlobalConstVectorElemType,
+ SymbolUseKind::GlobalConstMatrixElemType,
SymbolUseKind::AliasType,
SymbolUseKind::StructMemberType,
SymbolUseKind::ParameterType,
@@ -165,7 +165,7 @@
};
static constexpr SymbolUseKind kValueUseKinds[] = {
- SymbolUseKind::GlobalVarValue, SymbolUseKind::GlobalLetValue,
+ SymbolUseKind::GlobalVarValue, SymbolUseKind::GlobalConstValue,
SymbolUseKind::LocalVarValue, SymbolUseKind::LocalLetValue,
SymbolUseKind::NestedLocalVarValue, SymbolUseKind::NestedLocalLetValue,
SymbolUseKind::WorkgroupSizeValue,
@@ -182,7 +182,7 @@
case SymbolDeclKind::GlobalVar:
return out << "global var";
case SymbolDeclKind::GlobalConst:
- return out << "global let";
+ return out << "global const";
case SymbolDeclKind::Alias:
return out << "alias";
case SymbolDeclKind::Struct:
@@ -223,18 +223,18 @@
return out << "global var sampled_texture element type";
case SymbolUseKind::GlobalVarMultisampledTexElemType:
return out << "global var multisampled_texture element type";
- case SymbolUseKind::GlobalLetType:
- return out << "global let type";
- case SymbolUseKind::GlobalLetValue:
- return out << "global let value";
- case SymbolUseKind::GlobalLetArrayElemType:
- return out << "global let array element type";
- case SymbolUseKind::GlobalLetArraySizeValue:
- return out << "global let array size value";
- case SymbolUseKind::GlobalLetVectorElemType:
- return out << "global let vector element type";
- case SymbolUseKind::GlobalLetMatrixElemType:
- return out << "global let matrix element type";
+ case SymbolUseKind::GlobalConstType:
+ return out << "global const type";
+ case SymbolUseKind::GlobalConstValue:
+ return out << "global const value";
+ case SymbolUseKind::GlobalConstArrayElemType:
+ return out << "global const array element type";
+ case SymbolUseKind::GlobalConstArraySizeValue:
+ return out << "global const array size value";
+ case SymbolUseKind::GlobalConstVectorElemType:
+ return out << "global const vector element type";
+ case SymbolUseKind::GlobalConstMatrixElemType:
+ return out << "global const matrix element type";
case SymbolUseKind::AliasType:
return out << "alias type";
case SymbolUseKind::StructMemberType:
@@ -282,10 +282,10 @@
case SymbolUseKind::GlobalVarMatrixElemType:
case SymbolUseKind::GlobalVarSampledTexElemType:
case SymbolUseKind::GlobalVarMultisampledTexElemType:
- case SymbolUseKind::GlobalLetType:
- case SymbolUseKind::GlobalLetArrayElemType:
- case SymbolUseKind::GlobalLetVectorElemType:
- case SymbolUseKind::GlobalLetMatrixElemType:
+ case SymbolUseKind::GlobalConstType:
+ case SymbolUseKind::GlobalConstArrayElemType:
+ case SymbolUseKind::GlobalConstVectorElemType:
+ case SymbolUseKind::GlobalConstMatrixElemType:
case SymbolUseKind::AliasType:
case SymbolUseKind::StructMemberType:
case SymbolUseKind::ParameterType:
@@ -299,8 +299,8 @@
return "type";
case SymbolUseKind::GlobalVarValue:
case SymbolUseKind::GlobalVarArraySizeValue:
- case SymbolUseKind::GlobalLetValue:
- case SymbolUseKind::GlobalLetArraySizeValue:
+ case SymbolUseKind::GlobalConstValue:
+ case SymbolUseKind::GlobalConstArraySizeValue:
case SymbolUseKind::LocalVarValue:
case SymbolUseKind::LocalVarArraySizeValue:
case SymbolUseKind::LocalLetValue:
@@ -349,12 +349,12 @@
case SymbolUseKind::GlobalVarMatrixElemType:
case SymbolUseKind::GlobalVarSampledTexElemType:
case SymbolUseKind::GlobalVarMultisampledTexElemType:
- case SymbolUseKind::GlobalLetType:
- case SymbolUseKind::GlobalLetValue:
- case SymbolUseKind::GlobalLetArrayElemType:
- case SymbolUseKind::GlobalLetArraySizeValue:
- case SymbolUseKind::GlobalLetVectorElemType:
- case SymbolUseKind::GlobalLetMatrixElemType:
+ case SymbolUseKind::GlobalConstType:
+ case SymbolUseKind::GlobalConstValue:
+ case SymbolUseKind::GlobalConstArrayElemType:
+ case SymbolUseKind::GlobalConstArraySizeValue:
+ case SymbolUseKind::GlobalConstVectorElemType:
+ case SymbolUseKind::GlobalConstMatrixElemType:
case SymbolUseKind::AliasType:
case SymbolUseKind::StructMemberType:
case SymbolUseKind::WorkgroupSizeValue:
@@ -425,7 +425,7 @@
auto& b = *builder;
switch (kind) {
case SymbolDeclKind::GlobalVar:
- return b.Global(source, symbol, b.ty.i32(), ast::StorageClass::kPrivate);
+ return b.GlobalVar(source, symbol, b.ty.i32(), ast::StorageClass::kPrivate);
case SymbolDeclKind::GlobalConst:
return b.GlobalConst(source, symbol, b.ty.i32(), b.Expr(1_i));
case SymbolDeclKind::Alias:
@@ -468,70 +468,70 @@
switch (kind) {
case SymbolUseKind::GlobalVarType: {
auto* node = b.ty.type_name(source, symbol);
- b.Global(b.Sym(), node, ast::StorageClass::kPrivate);
+ b.GlobalVar(b.Sym(), node, ast::StorageClass::kPrivate);
return node;
}
case SymbolUseKind::GlobalVarArrayElemType: {
auto* node = b.ty.type_name(source, symbol);
- b.Global(b.Sym(), b.ty.array(node, 4_i), ast::StorageClass::kPrivate);
+ b.GlobalVar(b.Sym(), b.ty.array(node, 4_i), ast::StorageClass::kPrivate);
return node;
}
case SymbolUseKind::GlobalVarArraySizeValue: {
auto* node = b.Expr(source, symbol);
- b.Global(b.Sym(), b.ty.array(b.ty.i32(), node), ast::StorageClass::kPrivate);
+ b.GlobalVar(b.Sym(), b.ty.array(b.ty.i32(), node), ast::StorageClass::kPrivate);
return node;
}
case SymbolUseKind::GlobalVarVectorElemType: {
auto* node = b.ty.type_name(source, symbol);
- b.Global(b.Sym(), b.ty.vec3(node), ast::StorageClass::kPrivate);
+ b.GlobalVar(b.Sym(), b.ty.vec3(node), ast::StorageClass::kPrivate);
return node;
}
case SymbolUseKind::GlobalVarMatrixElemType: {
auto* node = b.ty.type_name(source, symbol);
- b.Global(b.Sym(), b.ty.mat3x4(node), ast::StorageClass::kPrivate);
+ b.GlobalVar(b.Sym(), b.ty.mat3x4(node), ast::StorageClass::kPrivate);
return node;
}
case SymbolUseKind::GlobalVarSampledTexElemType: {
auto* node = b.ty.type_name(source, symbol);
- b.Global(b.Sym(), b.ty.sampled_texture(ast::TextureDimension::k2d, node));
+ b.GlobalVar(b.Sym(), b.ty.sampled_texture(ast::TextureDimension::k2d, node));
return node;
}
case SymbolUseKind::GlobalVarMultisampledTexElemType: {
auto* node = b.ty.type_name(source, symbol);
- b.Global(b.Sym(), b.ty.multisampled_texture(ast::TextureDimension::k2d, node));
+ b.GlobalVar(b.Sym(), b.ty.multisampled_texture(ast::TextureDimension::k2d, node));
return node;
}
case SymbolUseKind::GlobalVarValue: {
auto* node = b.Expr(source, symbol);
- b.Global(b.Sym(), b.ty.i32(), ast::StorageClass::kPrivate, node);
+ b.GlobalVar(b.Sym(), b.ty.i32(), ast::StorageClass::kPrivate, node);
return node;
}
- case SymbolUseKind::GlobalLetType: {
+ case SymbolUseKind::GlobalConstType: {
auto* node = b.ty.type_name(source, symbol);
b.GlobalConst(b.Sym(), node, b.Expr(1_i));
return node;
}
- case SymbolUseKind::GlobalLetArrayElemType: {
+ case SymbolUseKind::GlobalConstArrayElemType: {
auto* node = b.ty.type_name(source, symbol);
b.GlobalConst(b.Sym(), b.ty.array(node, 4_i), b.Expr(1_i));
return node;
}
- case SymbolUseKind::GlobalLetArraySizeValue: {
+ case SymbolUseKind::GlobalConstArraySizeValue: {
auto* node = b.Expr(source, symbol);
b.GlobalConst(b.Sym(), b.ty.array(b.ty.i32(), node), b.Expr(1_i));
return node;
}
- case SymbolUseKind::GlobalLetVectorElemType: {
+ case SymbolUseKind::GlobalConstVectorElemType: {
auto* node = b.ty.type_name(source, symbol);
b.GlobalConst(b.Sym(), b.ty.vec3(node), b.Expr(1_i));
return node;
}
- case SymbolUseKind::GlobalLetMatrixElemType: {
+ case SymbolUseKind::GlobalConstMatrixElemType: {
auto* node = b.ty.type_name(source, symbol);
b.GlobalConst(b.Sym(), b.ty.mat3x4(node), b.Expr(1_i));
return node;
}
- case SymbolUseKind::GlobalLetValue: {
+ case SymbolUseKind::GlobalConstValue: {
auto* node = b.Expr(source, symbol);
b.GlobalConst(b.Sym(), b.ty.i32(), node);
return node;
@@ -722,7 +722,7 @@
Block(Assign(Expr(Source{{12, 34}}, "G"), 3.14_f)),
});
- Global(Source{{56, 78}}, "G", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
+ GlobalVar(Source{{56, 78}}, "G", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
Build();
}
@@ -772,7 +772,7 @@
TEST_F(ResolverDependencyGraphDeclSelfUse, GlobalVar) {
const Symbol symbol = Sym("SYMBOL");
- Global(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123_i));
+ GlobalVar(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123_i));
Build(R"(error: cyclic dependency found: 'SYMBOL' -> 'SYMBOL'
12:34 note: var 'SYMBOL' references var 'SYMBOL' here)");
}
@@ -781,7 +781,7 @@
const Symbol symbol = Sym("SYMBOL");
GlobalConst(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123_i));
Build(R"(error: cyclic dependency found: 'SYMBOL' -> 'SYMBOL'
-12:34 note: let 'SYMBOL' references let 'SYMBOL' here)");
+12:34 note: const 'SYMBOL' references const 'SYMBOL' here)");
}
TEST_F(ResolverDependencyGraphDeclSelfUse, LocalVar) {
@@ -899,7 +899,7 @@
TEST_F(ResolverDependencyGraphCyclicRefTest, GlobalVar_Direct) {
// var<private> V : i32 = V;
- Global(Source{{12, 34}}, "V", ty.i32(), Expr(Source{{56, 78}}, "V"));
+ GlobalVar(Source{{12, 34}}, "V", ty.i32(), Expr(Source{{56, 78}}, "V"));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -907,7 +907,7 @@
56:78 note: var 'V' references var 'V' here)");
}
-TEST_F(ResolverDependencyGraphCyclicRefTest, GlobalLet_Direct) {
+TEST_F(ResolverDependencyGraphCyclicRefTest, GlobalConst_Direct) {
// let V : i32 = V;
GlobalConst(Source{{12, 34}}, "V", ty.i32(), Expr(Source{{56, 78}}, "V"));
@@ -915,7 +915,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(12:34 error: cyclic dependency found: 'V' -> 'V'
-56:78 note: let 'V' references let 'V' here)");
+56:78 note: const 'V' references const 'V' here)");
}
TEST_F(ResolverDependencyGraphCyclicRefTest, GlobalVar_Indirect) {
@@ -923,9 +923,9 @@
// 2: var<private> X : i32 = Y;
// 3: var<private> Z : i32 = X;
- Global(Source{{1, 1}}, "Y", ty.i32(), Expr(Source{{1, 10}}, "Z"));
- Global(Source{{2, 1}}, "X", ty.i32(), Expr(Source{{2, 10}}, "Y"));
- Global(Source{{3, 1}}, "Z", ty.i32(), Expr(Source{{3, 10}}, "X"));
+ GlobalVar(Source{{1, 1}}, "Y", ty.i32(), Expr(Source{{1, 10}}, "Z"));
+ GlobalVar(Source{{2, 1}}, "X", ty.i32(), Expr(Source{{2, 10}}, "Y"));
+ GlobalVar(Source{{3, 1}}, "Z", ty.i32(), Expr(Source{{3, 10}}, "X"));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -935,10 +935,10 @@
2:10 note: var 'X' references var 'Y' here)");
}
-TEST_F(ResolverDependencyGraphCyclicRefTest, GlobalLet_Indirect) {
- // 1: let Y : i32 = Z;
- // 2: let X : i32 = Y;
- // 3: let Z : i32 = X;
+TEST_F(ResolverDependencyGraphCyclicRefTest, GlobalConst_Indirect) {
+ // 1: const Y : i32 = Z;
+ // 2: const X : i32 = Y;
+ // 3: const Z : i32 = X;
GlobalConst(Source{{1, 1}}, "Y", ty.i32(), Expr(Source{{1, 10}}, "Z"));
GlobalConst(Source{{2, 1}}, "X", ty.i32(), Expr(Source{{2, 10}}, "Y"));
@@ -947,9 +947,9 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(1:1 error: cyclic dependency found: 'Y' -> 'Z' -> 'X' -> 'Y'
-1:10 note: let 'Y' references let 'Z' here
-3:10 note: let 'Z' references let 'X' here
-2:10 note: let 'X' references let 'Y' here)");
+1:10 note: const 'Y' references const 'Z' here
+3:10 note: const 'Z' references const 'X' here
+2:10 note: const 'X' references const 'Y' here)");
}
TEST_F(ResolverDependencyGraphCyclicRefTest, Mixed_RecursiveDependencies) {
@@ -958,13 +958,13 @@
// 3: struct S { a : A };
// 4: var Z = L;
// 5: type R = A;
- // 6: let L : S = Z;
+ // 6: const L : S = Z;
Func(Source{{1, 1}}, "F", {}, ty.type_name(Source{{1, 5}}, "R"),
{Return(Expr(Source{{1, 10}}, "Z"))});
Alias(Source{{2, 1}}, "A", ty.type_name(Source{{2, 10}}, "S"));
Structure(Source{{3, 1}}, "S", {Member("a", ty.type_name(Source{{3, 10}}, "A"))});
- Global(Source{{4, 1}}, "Z", nullptr, Expr(Source{{4, 10}}, "L"));
+ GlobalVar(Source{{4, 1}}, "Z", nullptr, Expr(Source{{4, 10}}, "L"));
Alias(Source{{5, 1}}, "R", ty.type_name(Source{{5, 10}}, "A"));
GlobalConst(Source{{6, 1}}, "L", ty.type_name(Source{{5, 5}}, "S"), Expr(Source{{5, 10}}, "Z"));
@@ -974,8 +974,8 @@
2:10 note: alias 'A' references struct 'S' here
3:10 note: struct 'S' references alias 'A' here
4:1 error: cyclic dependency found: 'Z' -> 'L' -> 'Z'
-4:10 note: var 'Z' references let 'L' here
-5:10 note: let 'L' references var 'Z' here)");
+4:10 note: var 'Z' references const 'L' here
+5:10 note: const 'L' references var 'Z' here)");
}
} // namespace recursive_tests
@@ -1086,9 +1086,9 @@
// Although all enable directives in a valid WGSL program must go before any other global
// declaration, a transform may produce such a AST tree that has some declarations before enable
// nodes. DependencyGraph should deal with these cases.
- auto* var_1 = Global("SYMBOL1", ty.i32(), nullptr);
+ auto* var_1 = GlobalVar("SYMBOL1", ty.i32(), nullptr);
auto* enable_1 = Enable(ast::Extension::kF16);
- auto* var_2 = Global("SYMBOL2", ty.f32(), nullptr);
+ auto* var_2 = GlobalVar("SYMBOL2", ty.f32(), nullptr);
auto* enable_2 = Enable(ast::Extension::kF16);
EXPECT_THAT(AST().GlobalDeclarations(), ElementsAre(var_1, enable_1, var_2, enable_2));
@@ -1201,7 +1201,7 @@
const auto type_sym = Sym("TYPE");
const auto func_sym = Sym("FUNC");
- const auto* value_decl = Global(value_sym, ty.i32(), ast::StorageClass::kPrivate);
+ const auto* value_decl = GlobalVar(value_sym, ty.i32(), ast::StorageClass::kPrivate);
const auto* type_decl = Alias(type_sym, ty.i32());
const auto* func_decl = Func(func_sym, {}, ty.void_(), {});
@@ -1224,7 +1224,7 @@
Alias(Sym(), T);
Structure(Sym(), {Member(Sym(), T)});
- Global(Sym(), T, V);
+ GlobalVar(Sym(), T, V);
GlobalConst(Sym(), T, V);
Func(Sym(), //
{Param(Sym(), T)}, //
@@ -1261,23 +1261,23 @@
Discard(), //
}); //
// Exercise type traversal
- Global(Sym(), ty.atomic(T));
- Global(Sym(), ty.bool_());
- Global(Sym(), ty.i32());
- Global(Sym(), ty.u32());
- Global(Sym(), ty.f32());
- Global(Sym(), ty.array(T, V, 4));
- Global(Sym(), ty.vec3(T));
- Global(Sym(), ty.mat3x2(T));
- Global(Sym(), ty.pointer(T, ast::StorageClass::kPrivate));
- Global(Sym(), ty.sampled_texture(ast::TextureDimension::k2d, T));
- Global(Sym(), ty.depth_texture(ast::TextureDimension::k2d));
- Global(Sym(), ty.depth_multisampled_texture(ast::TextureDimension::k2d));
- Global(Sym(), ty.external_texture());
- Global(Sym(), ty.multisampled_texture(ast::TextureDimension::k2d, T));
- Global(Sym(), ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
- ast::Access::kRead)); //
- Global(Sym(), ty.sampler(ast::SamplerKind::kSampler));
+ GlobalVar(Sym(), ty.atomic(T));
+ GlobalVar(Sym(), ty.bool_());
+ GlobalVar(Sym(), ty.i32());
+ GlobalVar(Sym(), ty.u32());
+ GlobalVar(Sym(), ty.f32());
+ GlobalVar(Sym(), ty.array(T, V, 4));
+ GlobalVar(Sym(), ty.vec3(T));
+ GlobalVar(Sym(), ty.mat3x2(T));
+ GlobalVar(Sym(), ty.pointer(T, ast::StorageClass::kPrivate));
+ GlobalVar(Sym(), ty.sampled_texture(ast::TextureDimension::k2d, T));
+ GlobalVar(Sym(), ty.depth_texture(ast::TextureDimension::k2d));
+ GlobalVar(Sym(), ty.depth_multisampled_texture(ast::TextureDimension::k2d));
+ GlobalVar(Sym(), ty.external_texture());
+ GlobalVar(Sym(), ty.multisampled_texture(ast::TextureDimension::k2d, T));
+ GlobalVar(Sym(), ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
+ ast::Access::kRead)); //
+ GlobalVar(Sym(), ty.sampler(ast::SamplerKind::kSampler));
Func(Sym(), {}, ty.void_(), {});
#undef V
#undef T
@@ -1291,8 +1291,8 @@
}
TEST_F(ResolverDependencyGraphTraversalTest, InferredType) {
- // Check that the nullptr of the var / let type doesn't make things explode
- Global("a", nullptr, Expr(1_i));
+ // Check that the nullptr of the var / const / let type doesn't make things explode
+ GlobalVar("a", nullptr, Expr(1_i));
GlobalConst("b", nullptr, Expr(1_i));
WrapInFunction(Var("c", nullptr, Expr(1_i)), //
Let("d", nullptr, Expr(1_i)));
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index 525195f..7039fa4 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -39,7 +39,7 @@
TEST_F(ResolverFunctionValidationTest, ParameterMayShadowGlobal) {
// var<private> common_name : f32;
// fn func(common_name : f32) { }
- Global("common_name", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("common_name", ty.f32(), ast::StorageClass::kPrivate);
Func("func", {Param("common_name", ty.f32())}, ty.void_(), {});
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -241,8 +241,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: return statement type must match its function return "
- "type, returned 'abstract-int', expected 'void'");
+ "12:34 error: return statement type must match its function return type, returned "
+ "'abstract-int', expected 'void'");
}
TEST_F(ResolverFunctionValidationTest, VoidFunctionReturnsAFloat) {
@@ -251,8 +251,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: return statement type must match its function return "
- "type, returned 'abstract-float', expected 'void'");
+ "12:34 error: return statement type must match its function return type, returned "
+ "'abstract-float', expected 'void'");
}
TEST_F(ResolverFunctionValidationTest, VoidFunctionReturnsI32) {
@@ -261,8 +261,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: return statement type must match its function return "
- "type, returned 'i32', expected 'void'");
+ "12:34 error: return statement type must match its function return type, returned "
+ "'i32', expected 'void'");
}
TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementType_void_fail) {
@@ -287,8 +287,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: return statement type must match its function return "
- "type, returned 'void', expected 'f32'");
+ "12:34 error: return statement type must match its function return type, returned "
+ "'void', expected 'f32'");
}
TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementTypeF32_pass) {
@@ -310,8 +310,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: return statement type must match its function return "
- "type, returned 'i32', expected 'f32'");
+ "12:34 error: return statement type must match its function return type, returned "
+ "'i32', expected 'f32'");
}
TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementTypeF32Alias_pass) {
@@ -337,8 +337,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: return statement type must match its function return "
- "type, returned 'u32', expected 'f32'");
+ "12:34 error: return statement type must match its function return type, returned "
+ "'u32', expected 'f32'");
}
TEST_F(ResolverFunctionValidationTest, CannotCallEntryPoint) {
@@ -354,10 +354,19 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
-
R"(12:34 error: entry point functions cannot be the target of a function call)");
}
+TEST_F(ResolverFunctionValidationTest, CannotCallFunctionAtModuleScope) {
+ // fn F() -> i32 { return 1; }
+ // var x = F();
+ Func("F", {}, ty.i32(), {Return(1_i)});
+ GlobalVar("x", nullptr, Call(Source{{12, 34}}, "F"), ast::StorageClass::kPrivate);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), R"(12:34 error: functions cannot be called at module-scope)");
+}
+
TEST_F(ResolverFunctionValidationTest, PipelineStage_MustBeUnique_Fail) {
// @fragment
// @vertex
@@ -424,13 +433,12 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: cannot assign to function parameter\nnote: 'arg' is "
- "declared here:");
+ "12:34 error: cannot assign to function parameter\nnote: 'arg' is declared here:");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_GoodType_ConstU32) {
- // let x = 4u;
- // let x = 8u;
+ // const x = 4u;
+ // const x = 8u;
// @compute @workgroup_size(x, y, 16u)
// fn main() {}
auto* x = GlobalConst("x", ty.u32(), Expr(4_u));
@@ -517,7 +525,7 @@
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_TypeMismatch) {
- // let x = 64u;
+ // const x = 64u;
// @compute @workgroup_size(1i, x)
// fn main() {}
GlobalConst("x", ty.u32(), Expr(64_u));
@@ -530,8 +538,8 @@
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_TypeMismatch2) {
- // let x = 64u;
- // let y = 32i;
+ // const x = 64u;
+ // const y = 32i;
// @compute @workgroup_size(x, y)
// fn main() {}
GlobalConst("x", ty.u32(), Expr(64_u));
@@ -543,9 +551,10 @@
EXPECT_EQ(r()->error(),
"12:34 error: workgroup_size arguments must be of the same type, either i32 or u32");
}
+
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Mismatch_ConstU32) {
- // let x = 4u;
- // let x = 8u;
+ // const x = 4u;
+ // const x = 8u;
// @compute @workgroup_size(x, y, 16i)
// fn main() {}
GlobalConst("x", ty.u32(), Expr(4_u));
@@ -567,8 +576,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size argument must be either literal or "
- "module-scope constant of type i32 or u32");
+ "12:34 error: workgroup_size argument must be either a literal, constant, or "
+ "overridable of type abstract-integer, i32 or u32");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Literal_Negative) {
@@ -594,7 +603,7 @@
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_BadType) {
- // let x = 64.0;
+ // const x = 64.0;
// @compute @workgroup_size(x)
// fn main() {}
GlobalConst("x", ty.f32(), Expr(64_f));
@@ -603,12 +612,12 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size argument must be either literal or "
- "module-scope constant of type i32 or u32");
+ "12:34 error: workgroup_size argument must be either a literal, constant, or "
+ "overridable of type abstract-integer, i32 or u32");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_Negative) {
- // let x = -2i;
+ // const x = -2i;
// @compute @workgroup_size(x)
// fn main() {}
GlobalConst("x", ty.i32(), Expr(-2_i));
@@ -620,7 +629,7 @@
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_Zero) {
- // let x = 0i;
+ // const x = 0i;
// @compute @workgroup_size(x)
// fn main() {}
GlobalConst("x", ty.i32(), Expr(0_i));
@@ -632,7 +641,7 @@
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_NestedZeroValueConstructor) {
- // let x = i32(i32(i32()));
+ // const x = i32(i32(i32()));
// @compute @workgroup_size(x)
// fn main() {}
GlobalConst("x", ty.i32(), Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32()))));
@@ -647,14 +656,14 @@
// var<private> x = 64i;
// @compute @workgroup_size(x)
// fn main() {}
- Global("x", ty.i32(), ast::StorageClass::kPrivate, Expr(64_i));
+ GlobalVar("x", ty.i32(), ast::StorageClass::kPrivate, Expr(64_i));
Func("main", {}, ty.void_(), {},
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, "x"))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size argument must be either literal or "
- "module-scope constant of type i32 or u32");
+ "12:34 error: workgroup_size argument must be either a literal, constant, or "
+ "overridable of type abstract-integer, i32 or u32");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_InvalidExpr) {
@@ -666,8 +675,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size argument must be either a literal or "
- "a module-scope constant");
+ "12:34 error: workgroup_size argument must be either a literal, constant, or "
+ "overridable of type abstract-integer, i32 or u32");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_NonPlain) {
@@ -754,7 +763,7 @@
TEST_F(ResolverFunctionValidationTest, ParameterVectorNoType) {
// fn f(p : vec3) {}
- Func(Source{{12, 34}}, "f", {Param("p", create<ast::Vector>(Source{{12, 34}}, nullptr, 3))},
+ Func(Source{{12, 34}}, "f", {Param("p", create<ast::Vector>(Source{{12, 34}}, nullptr, 3u))},
ty.void_(), {});
EXPECT_FALSE(r()->Resolve());
@@ -764,8 +773,8 @@
TEST_F(ResolverFunctionValidationTest, ParameterMatrixNoType) {
// fn f(p : vec3) {}
- Func(Source{{12, 34}}, "f", {Param("p", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3, 3))},
- ty.void_(), {});
+ Func(Source{{12, 34}}, "f",
+ {Param("p", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3u, 3u))}, ty.void_(), {});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
diff --git a/src/tint/resolver/host_shareable_validation_test.cc b/src/tint/resolver/host_shareable_validation_test.cc
index 01fbfb0..d50057c 100644
--- a/src/tint/resolver/host_shareable_validation_test.cc
+++ b/src/tint/resolver/host_shareable_validation_test.cc
@@ -26,11 +26,11 @@
TEST_F(ResolverHostShareableValidationTest, BoolMember) {
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.bool_())});
- Global(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -38,17 +38,17 @@
r()->error(),
R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
12:34 note: while analysing structure member S.x
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) {
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.vec3<bool>())});
- Global(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -56,18 +56,18 @@
r()->error(),
R"(56:78 error: Type 'vec3<bool>' cannot be used in storage class 'storage' as it is non-host-shareable
12:34 note: while analysing structure member S.x
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverHostShareableValidationTest, Aliases) {
auto* a1 = Alias("a1", ty.bool_());
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.Of(a1))});
auto* a2 = Alias("a2", ty.Of(s));
- Global(Source{{56, 78}}, "g", ty.Of(a2), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -75,7 +75,7 @@
r()->error(),
R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
12:34 note: while analysing structure member S.x
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverHostShareableValidationTest, NestedStructures) {
@@ -85,11 +85,11 @@
auto* s = Structure("S", {Member(Source{{7, 8}}, "m", ty.Of(i3))});
- Global(Source{{9, 10}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{9, 10}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -100,19 +100,23 @@
3:4 note: while analysing structure member I2.y
5:6 note: while analysing structure member I3.z
7:8 note: while analysing structure member S.m
-9:10 note: while instantiating variable g)");
+9:10 note: while instantiating 'var' g)");
}
TEST_F(ResolverHostShareableValidationTest, NoError) {
+ Enable(ast::Extension::kF16);
+
auto* i1 = Structure("I1", {
- Member(Source{{1, 1}}, "x1", ty.f32()),
- Member(Source{{2, 1}}, "y1", ty.vec3<f32>()),
- Member(Source{{3, 1}}, "z1", ty.array<i32, 4>()),
+ Member(Source{{1, 1}}, "w1", ty.f16()),
+ Member(Source{{2, 1}}, "x1", ty.f32()),
+ Member(Source{{3, 1}}, "y1", ty.vec3<f32>()),
+ Member(Source{{4, 1}}, "z1", ty.array<i32, 4>()),
});
auto* a1 = Alias("a1", ty.Of(i1));
auto* i2 = Structure("I2", {
- Member(Source{{4, 1}}, "x2", ty.mat2x2<f32>()),
- Member(Source{{5, 1}}, "y2", ty.Of(i1)),
+ Member(Source{{5, 1}}, "x2", ty.mat2x2<f32>()),
+ Member(Source{{6, 1}}, "w2", ty.mat3x4<f16>()),
+ Member(Source{{7, 1}}, "z2", ty.Of(i1)),
});
auto* a2 = Alias("a2", ty.Of(i2));
auto* i3 = Structure("I3", {
@@ -123,11 +127,11 @@
auto* s = Structure("S", {Member(Source{{7, 8}}, "m", ty.Of(i3))});
- Global(Source{{9, 10}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{9, 10}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
WrapInFunction();
ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/increment_decrement_validation_test.cc b/src/tint/resolver/increment_decrement_validation_test.cc
index b8e3aa1..5061e49 100644
--- a/src/tint/resolver/increment_decrement_validation_test.cc
+++ b/src/tint/resolver/increment_decrement_validation_test.cc
@@ -127,7 +127,7 @@
TEST_F(ResolverIncrementDecrementValidationTest, Atomic) {
// var<workgroup> a : atomic<i32>;
// a++;
- Global(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::StorageClass::kWorkgroup);
+ GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::StorageClass::kWorkgroup);
WrapInFunction(Increment(Expr(Source{{56, 78}}, "a")));
EXPECT_FALSE(r()->Resolve());
@@ -187,8 +187,8 @@
// {
// a++;
// }
- Global(Source{{12, 34}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
+ GroupAndBinding(0, 0));
WrapInFunction(Increment(Source{{56, 78}}, "a"));
EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/inferred_type_test.cc b/src/tint/resolver/inferred_type_test.cc
index 4d01f7e..a183b20 100644
--- a/src/tint/resolver/inferred_type_test.cc
+++ b/src/tint/resolver/inferred_type_test.cc
@@ -75,30 +75,32 @@
using ResolverInferredTypeParamTest = ResolverTestWithParam<Params>;
-TEST_P(ResolverInferredTypeParamTest, GlobalLet_Pass) {
+TEST_P(ResolverInferredTypeParamTest, GlobalConst_Pass) {
auto& params = GetParam();
auto* expected_type = params.create_expected_type(*this);
- // let a = <type constructor>;
+ // const a = <type constructor>;
auto* ctor_expr = params.create_value(*this, 0);
- auto* var = GlobalConst("a", nullptr, ctor_expr);
+ auto* a = GlobalConst("a", nullptr, ctor_expr);
WrapInFunction();
EXPECT_TRUE(r()->Resolve()) << r()->error();
- EXPECT_EQ(TypeOf(var), expected_type);
+ EXPECT_EQ(TypeOf(a), expected_type);
}
-TEST_P(ResolverInferredTypeParamTest, GlobalVar_Fail) {
+TEST_P(ResolverInferredTypeParamTest, GlobalVar_Pass) {
auto& params = GetParam();
+ auto* expected_type = params.create_expected_type(*this);
+
// var a = <type constructor>;
auto* ctor_expr = params.create_value(*this, 0);
- Global(Source{{12, 34}}, "a", nullptr, ast::StorageClass::kPrivate, ctor_expr);
+ auto* var = GlobalVar("a", nullptr, ast::StorageClass::kPrivate, ctor_expr);
WrapInFunction();
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: module-scope 'var' declaration must specify a type");
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ EXPECT_EQ(TypeOf(var)->UnwrapRef(), expected_type);
}
TEST_P(ResolverInferredTypeParamTest, LocalLet_Pass) {
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index eb8f30e..d746a6c 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -19,6 +19,7 @@
#include <unordered_map>
#include <utility>
+#include "src/tint/ast/binary_expression.h"
#include "src/tint/program_builder.h"
#include "src/tint/sem/abstract_float.h"
#include "src/tint/sem/abstract_int.h"
@@ -341,6 +342,14 @@
return state.builder.create<sem::Bool>();
}
+const sem::F16* build_f16(MatchState& state) {
+ return state.builder.create<sem::F16>();
+}
+
+bool match_f16(const sem::Type* ty) {
+ return ty->IsAnyOf<Any, sem::F16, sem::AbstractNumeric>();
+}
+
const sem::F32* build_f32(MatchState& state) {
return state.builder.create<sem::F32>();
}
@@ -1291,8 +1300,8 @@
// Conversion.
return utils::GetOrCreate(converters, match, [&]() {
auto param = builder.create<sem::Parameter>(
- nullptr, 0, match.parameters[0].type, ast::StorageClass::kNone, ast::Access::kUndefined,
- match.parameters[0].usage);
+ nullptr, 0u, match.parameters[0].type, ast::StorageClass::kNone,
+ ast::Access::kUndefined, match.parameters[0].usage);
return builder.create<sem::TypeConversion>(match.return_type, param);
});
}
diff --git a/src/tint/resolver/intrinsic_table.h b/src/tint/resolver/intrinsic_table.h
index 058b253..d10f7bb 100644
--- a/src/tint/resolver/intrinsic_table.h
+++ b/src/tint/resolver/intrinsic_table.h
@@ -19,6 +19,8 @@
#include <string>
#include <vector>
+#include "src/tint/ast/binary_expression.h"
+#include "src/tint/ast/unary_op.h"
#include "src/tint/resolver/const_eval.h"
#include "src/tint/resolver/ctor_conv_intrinsic.h"
#include "src/tint/sem/builtin.h"
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl
index 92a11f2..7869059 100644
--- a/src/tint/resolver/intrinsic_table.inl
+++ b/src/tint/resolver/intrinsic_table.inl
@@ -190,8 +190,35 @@
return "f32";
}
+/// TypeMatcher for 'type f16'
+/// @see src/tint/intrinsics.def:79:21
+class F16 : public TypeMatcher {
+ public:
+ /// Checks whether the given type matches the matcher rules.
+ /// Match may define and refine the template types and numbers in state.
+ /// @param state the MatchState
+ /// @param type the type to match
+ /// @returns the canonicalized type on match, otherwise nullptr
+ const sem::Type* Match(MatchState& state,
+ const sem::Type* type) const override;
+ /// @param state the MatchState
+ /// @return a string representation of the matcher.
+ std::string String(MatchState* state) const override;
+};
+
+const sem::Type* F16::Match(MatchState& state, const sem::Type* ty) const {
+ if (!match_f16(ty)) {
+ return nullptr;
+ }
+ return build_f16(state);
+}
+
+std::string F16::String(MatchState*) const {
+ return "f16";
+}
+
/// TypeMatcher for 'type vec2'
-/// @see src/tint/intrinsics.def:79:6
+/// @see src/tint/intrinsics.def:80:6
class Vec2 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -224,7 +251,7 @@
}
/// TypeMatcher for 'type vec3'
-/// @see src/tint/intrinsics.def:80:6
+/// @see src/tint/intrinsics.def:81:6
class Vec3 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -257,7 +284,7 @@
}
/// TypeMatcher for 'type vec4'
-/// @see src/tint/intrinsics.def:81:6
+/// @see src/tint/intrinsics.def:82:6
class Vec4 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -290,7 +317,7 @@
}
/// TypeMatcher for 'type mat2x2'
-/// @see src/tint/intrinsics.def:82:6
+/// @see src/tint/intrinsics.def:83:6
class Mat2X2 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -323,7 +350,7 @@
}
/// TypeMatcher for 'type mat2x3'
-/// @see src/tint/intrinsics.def:83:6
+/// @see src/tint/intrinsics.def:84:6
class Mat2X3 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -356,7 +383,7 @@
}
/// TypeMatcher for 'type mat2x4'
-/// @see src/tint/intrinsics.def:84:6
+/// @see src/tint/intrinsics.def:85:6
class Mat2X4 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -389,7 +416,7 @@
}
/// TypeMatcher for 'type mat3x2'
-/// @see src/tint/intrinsics.def:85:6
+/// @see src/tint/intrinsics.def:86:6
class Mat3X2 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -422,7 +449,7 @@
}
/// TypeMatcher for 'type mat3x3'
-/// @see src/tint/intrinsics.def:86:6
+/// @see src/tint/intrinsics.def:87:6
class Mat3X3 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -455,7 +482,7 @@
}
/// TypeMatcher for 'type mat3x4'
-/// @see src/tint/intrinsics.def:87:6
+/// @see src/tint/intrinsics.def:88:6
class Mat3X4 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -488,7 +515,7 @@
}
/// TypeMatcher for 'type mat4x2'
-/// @see src/tint/intrinsics.def:88:6
+/// @see src/tint/intrinsics.def:89:6
class Mat4X2 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -521,7 +548,7 @@
}
/// TypeMatcher for 'type mat4x3'
-/// @see src/tint/intrinsics.def:89:6
+/// @see src/tint/intrinsics.def:90:6
class Mat4X3 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -554,7 +581,7 @@
}
/// TypeMatcher for 'type mat4x4'
-/// @see src/tint/intrinsics.def:90:6
+/// @see src/tint/intrinsics.def:91:6
class Mat4X4 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -587,7 +614,7 @@
}
/// TypeMatcher for 'type vec'
-/// @see src/tint/intrinsics.def:91:34
+/// @see src/tint/intrinsics.def:92:34
class Vec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -628,7 +655,7 @@
}
/// TypeMatcher for 'type mat'
-/// @see src/tint/intrinsics.def:92:34
+/// @see src/tint/intrinsics.def:93:34
class Mat : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -675,7 +702,7 @@
}
/// TypeMatcher for 'type ptr'
-/// @see src/tint/intrinsics.def:93:6
+/// @see src/tint/intrinsics.def:94:6
class Ptr : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -720,7 +747,7 @@
}
/// TypeMatcher for 'type atomic'
-/// @see src/tint/intrinsics.def:94:6
+/// @see src/tint/intrinsics.def:95:6
class Atomic : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -753,7 +780,7 @@
}
/// TypeMatcher for 'type array'
-/// @see src/tint/intrinsics.def:95:6
+/// @see src/tint/intrinsics.def:96:6
class Array : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -786,7 +813,7 @@
}
/// TypeMatcher for 'type sampler'
-/// @see src/tint/intrinsics.def:96:6
+/// @see src/tint/intrinsics.def:97:6
class Sampler : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -813,7 +840,7 @@
}
/// TypeMatcher for 'type sampler_comparison'
-/// @see src/tint/intrinsics.def:97:6
+/// @see src/tint/intrinsics.def:98:6
class SamplerComparison : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -840,7 +867,7 @@
}
/// TypeMatcher for 'type texture_1d'
-/// @see src/tint/intrinsics.def:98:6
+/// @see src/tint/intrinsics.def:99:6
class Texture1D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -873,7 +900,7 @@
}
/// TypeMatcher for 'type texture_2d'
-/// @see src/tint/intrinsics.def:99:6
+/// @see src/tint/intrinsics.def:100:6
class Texture2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -906,7 +933,7 @@
}
/// TypeMatcher for 'type texture_2d_array'
-/// @see src/tint/intrinsics.def:100:6
+/// @see src/tint/intrinsics.def:101:6
class Texture2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -939,7 +966,7 @@
}
/// TypeMatcher for 'type texture_3d'
-/// @see src/tint/intrinsics.def:101:6
+/// @see src/tint/intrinsics.def:102:6
class Texture3D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -972,7 +999,7 @@
}
/// TypeMatcher for 'type texture_cube'
-/// @see src/tint/intrinsics.def:102:6
+/// @see src/tint/intrinsics.def:103:6
class TextureCube : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1005,7 +1032,7 @@
}
/// TypeMatcher for 'type texture_cube_array'
-/// @see src/tint/intrinsics.def:103:6
+/// @see src/tint/intrinsics.def:104:6
class TextureCubeArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1038,7 +1065,7 @@
}
/// TypeMatcher for 'type texture_multisampled_2d'
-/// @see src/tint/intrinsics.def:104:6
+/// @see src/tint/intrinsics.def:105:6
class TextureMultisampled2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1071,7 +1098,7 @@
}
/// TypeMatcher for 'type texture_depth_2d'
-/// @see src/tint/intrinsics.def:105:6
+/// @see src/tint/intrinsics.def:106:6
class TextureDepth2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1098,7 +1125,7 @@
}
/// TypeMatcher for 'type texture_depth_2d_array'
-/// @see src/tint/intrinsics.def:106:6
+/// @see src/tint/intrinsics.def:107:6
class TextureDepth2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1125,7 +1152,7 @@
}
/// TypeMatcher for 'type texture_depth_cube'
-/// @see src/tint/intrinsics.def:107:6
+/// @see src/tint/intrinsics.def:108:6
class TextureDepthCube : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1152,7 +1179,7 @@
}
/// TypeMatcher for 'type texture_depth_cube_array'
-/// @see src/tint/intrinsics.def:108:6
+/// @see src/tint/intrinsics.def:109:6
class TextureDepthCubeArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1179,7 +1206,7 @@
}
/// TypeMatcher for 'type texture_depth_multisampled_2d'
-/// @see src/tint/intrinsics.def:109:6
+/// @see src/tint/intrinsics.def:110:6
class TextureDepthMultisampled2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1206,7 +1233,7 @@
}
/// TypeMatcher for 'type texture_storage_1d'
-/// @see src/tint/intrinsics.def:110:6
+/// @see src/tint/intrinsics.def:111:6
class TextureStorage1D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1245,7 +1272,7 @@
}
/// TypeMatcher for 'type texture_storage_2d'
-/// @see src/tint/intrinsics.def:111:6
+/// @see src/tint/intrinsics.def:112:6
class TextureStorage2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1284,7 +1311,7 @@
}
/// TypeMatcher for 'type texture_storage_2d_array'
-/// @see src/tint/intrinsics.def:112:6
+/// @see src/tint/intrinsics.def:113:6
class TextureStorage2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1323,7 +1350,7 @@
}
/// TypeMatcher for 'type texture_storage_3d'
-/// @see src/tint/intrinsics.def:113:6
+/// @see src/tint/intrinsics.def:114:6
class TextureStorage3D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1362,7 +1389,7 @@
}
/// TypeMatcher for 'type texture_external'
-/// @see src/tint/intrinsics.def:114:6
+/// @see src/tint/intrinsics.def:115:6
class TextureExternal : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1389,7 +1416,7 @@
}
/// TypeMatcher for 'type __modf_result'
-/// @see src/tint/intrinsics.def:116:6
+/// @see src/tint/intrinsics.def:117:6
class ModfResult : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1416,7 +1443,7 @@
}
/// TypeMatcher for 'type __modf_result_vec'
-/// @see src/tint/intrinsics.def:117:39
+/// @see src/tint/intrinsics.def:118:39
class ModfResultVec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1451,7 +1478,7 @@
}
/// TypeMatcher for 'type __frexp_result'
-/// @see src/tint/intrinsics.def:118:6
+/// @see src/tint/intrinsics.def:119:6
class FrexpResult : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1478,7 +1505,7 @@
}
/// TypeMatcher for 'type __frexp_result_vec'
-/// @see src/tint/intrinsics.def:119:40
+/// @see src/tint/intrinsics.def:120:40
class FrexpResultVec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1513,7 +1540,7 @@
}
/// TypeMatcher for 'type __atomic_compare_exchange_result'
-/// @see src/tint/intrinsics.def:121:6
+/// @see src/tint/intrinsics.def:122:6
class AtomicCompareExchangeResult : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1545,8 +1572,43 @@
return "__atomic_compare_exchange_result<" + T + ">";
}
+/// TypeMatcher for 'match f32f16'
+/// @see src/tint/intrinsics.def:130:7
+class F32F16 : public TypeMatcher {
+ public:
+ /// Checks whether the given type matches the matcher rules, and returns the
+ /// expected, canonicalized type on success.
+ /// Match may define and refine the template types and numbers in state.
+ /// @param state the MatchState
+ /// @param type the type to match
+ /// @returns the canonicalized type on match, otherwise nullptr
+ const sem::Type* Match(MatchState& state,
+ const sem::Type* type) const override;
+ /// @param state the MatchState
+ /// @return a string representation of the matcher.
+ std::string String(MatchState* state) const override;
+};
+
+const sem::Type* F32F16::Match(MatchState& state, const sem::Type* ty) const {
+ if (match_f32(ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(ty)) {
+ return build_f16(state);
+ }
+ return nullptr;
+}
+
+std::string F32F16::String(MatchState*) const {
+ std::stringstream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << F32().String(nullptr) << " or " << F16().String(nullptr);
+ return ss.str();
+}
+
/// TypeMatcher for 'match fiu32'
-/// @see src/tint/intrinsics.def:129:7
+/// @see src/tint/intrinsics.def:131:7
class Fiu32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1584,7 +1646,7 @@
}
/// TypeMatcher for 'match fi32'
-/// @see src/tint/intrinsics.def:130:7
+/// @see src/tint/intrinsics.def:132:7
class Fi32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1619,7 +1681,7 @@
}
/// TypeMatcher for 'match iu32'
-/// @see src/tint/intrinsics.def:131:7
+/// @see src/tint/intrinsics.def:133:7
class Iu32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1654,7 +1716,7 @@
}
/// TypeMatcher for 'match scalar'
-/// @see src/tint/intrinsics.def:132:7
+/// @see src/tint/intrinsics.def:134:7
class Scalar : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1680,6 +1742,9 @@
if (match_f32(ty)) {
return build_f32(state);
}
+ if (match_f16(ty)) {
+ return build_f16(state);
+ }
if (match_bool(ty)) {
return build_bool(state);
}
@@ -1690,12 +1755,12 @@
std::stringstream ss;
// Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
// template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << F32().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
+ ss << F32().String(nullptr) << ", " << F16().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
return ss.str();
}
/// TypeMatcher for 'match abstract_or_scalar'
-/// @see src/tint/intrinsics.def:133:7
+/// @see src/tint/intrinsics.def:135:7
class AbstractOrScalar : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1727,6 +1792,9 @@
if (match_f32(ty)) {
return build_f32(state);
}
+ if (match_f16(ty)) {
+ return build_f16(state);
+ }
if (match_bool(ty)) {
return build_bool(state);
}
@@ -1737,12 +1805,12 @@
std::stringstream ss;
// Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
// template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Ai().String(nullptr) << ", " << Af().String(nullptr) << ", " << F32().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
+ ss << Ai().String(nullptr) << ", " << Af().String(nullptr) << ", " << F32().String(nullptr) << ", " << F16().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
return ss.str();
}
/// TypeMatcher for 'match af_f32'
-/// @see src/tint/intrinsics.def:134:7
+/// @see src/tint/intrinsics.def:136:7
class AfF32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1776,8 +1844,46 @@
return ss.str();
}
+/// TypeMatcher for 'match af_f32f16'
+/// @see src/tint/intrinsics.def:137:7
+class AfF32F16 : public TypeMatcher {
+ public:
+ /// Checks whether the given type matches the matcher rules, and returns the
+ /// expected, canonicalized type on success.
+ /// Match may define and refine the template types and numbers in state.
+ /// @param state the MatchState
+ /// @param type the type to match
+ /// @returns the canonicalized type on match, otherwise nullptr
+ const sem::Type* Match(MatchState& state,
+ const sem::Type* type) const override;
+ /// @param state the MatchState
+ /// @return a string representation of the matcher.
+ std::string String(MatchState* state) const override;
+};
+
+const sem::Type* AfF32F16::Match(MatchState& state, const sem::Type* ty) const {
+ if (match_af(ty)) {
+ return build_af(state);
+ }
+ if (match_f32(ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(ty)) {
+ return build_f16(state);
+ }
+ return nullptr;
+}
+
+std::string AfF32F16::String(MatchState*) const {
+ std::stringstream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << Af().String(nullptr) << ", " << F32().String(nullptr) << " or " << F16().String(nullptr);
+ return ss.str();
+}
+
/// TypeMatcher for 'match scalar_no_f32'
-/// @see src/tint/intrinsics.def:135:7
+/// @see src/tint/intrinsics.def:138:7
class ScalarNoF32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1800,6 +1906,9 @@
if (match_u32(ty)) {
return build_u32(state);
}
+ if (match_f16(ty)) {
+ return build_f16(state);
+ }
if (match_bool(ty)) {
return build_bool(state);
}
@@ -1810,12 +1919,53 @@
std::stringstream ss;
// Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
// template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
+ ss << I32().String(nullptr) << ", " << F16().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
+ return ss.str();
+}
+
+/// TypeMatcher for 'match scalar_no_f16'
+/// @see src/tint/intrinsics.def:139:7
+class ScalarNoF16 : public TypeMatcher {
+ public:
+ /// Checks whether the given type matches the matcher rules, and returns the
+ /// expected, canonicalized type on success.
+ /// Match may define and refine the template types and numbers in state.
+ /// @param state the MatchState
+ /// @param type the type to match
+ /// @returns the canonicalized type on match, otherwise nullptr
+ const sem::Type* Match(MatchState& state,
+ const sem::Type* type) const override;
+ /// @param state the MatchState
+ /// @return a string representation of the matcher.
+ std::string String(MatchState* state) const override;
+};
+
+const sem::Type* ScalarNoF16::Match(MatchState& state, const sem::Type* ty) const {
+ if (match_i32(ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(ty)) {
+ return build_u32(state);
+ }
+ if (match_f32(ty)) {
+ return build_f32(state);
+ }
+ if (match_bool(ty)) {
+ return build_bool(state);
+ }
+ return nullptr;
+}
+
+std::string ScalarNoF16::String(MatchState*) const {
+ std::stringstream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << F32().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
return ss.str();
}
/// TypeMatcher for 'match scalar_no_i32'
-/// @see src/tint/intrinsics.def:136:7
+/// @see src/tint/intrinsics.def:140:7
class ScalarNoI32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1838,6 +1988,9 @@
if (match_f32(ty)) {
return build_f32(state);
}
+ if (match_f16(ty)) {
+ return build_f16(state);
+ }
if (match_bool(ty)) {
return build_bool(state);
}
@@ -1848,12 +2001,12 @@
std::stringstream ss;
// Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
// template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << F32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
+ ss << F32().String(nullptr) << ", " << F16().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
return ss.str();
}
/// TypeMatcher for 'match scalar_no_u32'
-/// @see src/tint/intrinsics.def:137:7
+/// @see src/tint/intrinsics.def:141:7
class ScalarNoU32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1876,6 +2029,9 @@
if (match_f32(ty)) {
return build_f32(state);
}
+ if (match_f16(ty)) {
+ return build_f16(state);
+ }
if (match_bool(ty)) {
return build_bool(state);
}
@@ -1886,12 +2042,12 @@
std::stringstream ss;
// Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
// template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << F32().String(nullptr) << ", " << I32().String(nullptr) << " or " << Bool().String(nullptr);
+ ss << F32().String(nullptr) << ", " << F16().String(nullptr) << ", " << I32().String(nullptr) << " or " << Bool().String(nullptr);
return ss.str();
}
/// TypeMatcher for 'match scalar_no_bool'
-/// @see src/tint/intrinsics.def:138:7
+/// @see src/tint/intrinsics.def:142:7
class ScalarNoBool : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1917,6 +2073,9 @@
if (match_f32(ty)) {
return build_f32(state);
}
+ if (match_f16(ty)) {
+ return build_f16(state);
+ }
return nullptr;
}
@@ -1924,12 +2083,12 @@
std::stringstream ss;
// Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
// template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << F32().String(nullptr) << ", " << I32().String(nullptr) << " or " << U32().String(nullptr);
+ ss << F32().String(nullptr) << ", " << F16().String(nullptr) << ", " << I32().String(nullptr) << " or " << U32().String(nullptr);
return ss.str();
}
/// EnumMatcher for 'match f32_texel_format'
-/// @see src/tint/intrinsics.def:149:7
+/// @see src/tint/intrinsics.def:153:7
class F32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -1962,7 +2121,7 @@
}
/// EnumMatcher for 'match i32_texel_format'
-/// @see src/tint/intrinsics.def:151:7
+/// @see src/tint/intrinsics.def:155:7
class I32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -1994,7 +2153,7 @@
}
/// EnumMatcher for 'match u32_texel_format'
-/// @see src/tint/intrinsics.def:153:7
+/// @see src/tint/intrinsics.def:157:7
class U32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2026,7 +2185,7 @@
}
/// EnumMatcher for 'match write_only'
-/// @see src/tint/intrinsics.def:156:7
+/// @see src/tint/intrinsics.def:160:7
class WriteOnly : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2052,7 +2211,7 @@
}
/// EnumMatcher for 'match function_private_workgroup'
-/// @see src/tint/intrinsics.def:158:7
+/// @see src/tint/intrinsics.def:162:7
class FunctionPrivateWorkgroup : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2082,7 +2241,7 @@
}
/// EnumMatcher for 'match workgroup_or_storage'
-/// @see src/tint/intrinsics.def:159:7
+/// @see src/tint/intrinsics.def:163:7
class WorkgroupOrStorage : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2199,6 +2358,7 @@
I32 I32_;
U32 U32_;
F32 F32_;
+ F16 F16_;
Vec2 Vec2_;
Vec3 Vec3_;
Vec4 Vec4_;
@@ -2240,13 +2400,16 @@
FrexpResult FrexpResult_;
FrexpResultVec FrexpResultVec_;
AtomicCompareExchangeResult AtomicCompareExchangeResult_;
+ F32F16 F32F16_;
Fiu32 Fiu32_;
Fi32 Fi32_;
Iu32 Iu32_;
Scalar Scalar_;
AbstractOrScalar AbstractOrScalar_;
AfF32 AfF32_;
+ AfF32F16 AfF32F16_;
ScalarNoF32 ScalarNoF32_;
+ ScalarNoF16 ScalarNoF16_;
ScalarNoI32 ScalarNoI32_;
ScalarNoU32 ScalarNoU32_;
ScalarNoBool ScalarNoBool_;
@@ -2267,7 +2430,7 @@
~Matchers();
/// The template types, types, and type matchers
- TypeMatcher const* const type[59] = {
+ TypeMatcher const* const type[63] = {
/* [0] */ &template_type_0_,
/* [1] */ &template_type_1_,
/* [2] */ &Bool_,
@@ -2276,57 +2439,61 @@
/* [5] */ &I32_,
/* [6] */ &U32_,
/* [7] */ &F32_,
- /* [8] */ &Vec2_,
- /* [9] */ &Vec3_,
- /* [10] */ &Vec4_,
- /* [11] */ &Mat2X2_,
- /* [12] */ &Mat2X3_,
- /* [13] */ &Mat2X4_,
- /* [14] */ &Mat3X2_,
- /* [15] */ &Mat3X3_,
- /* [16] */ &Mat3X4_,
- /* [17] */ &Mat4X2_,
- /* [18] */ &Mat4X3_,
- /* [19] */ &Mat4X4_,
- /* [20] */ &Vec_,
- /* [21] */ &Mat_,
- /* [22] */ &Ptr_,
- /* [23] */ &Atomic_,
- /* [24] */ &Array_,
- /* [25] */ &Sampler_,
- /* [26] */ &SamplerComparison_,
- /* [27] */ &Texture1D_,
- /* [28] */ &Texture2D_,
- /* [29] */ &Texture2DArray_,
- /* [30] */ &Texture3D_,
- /* [31] */ &TextureCube_,
- /* [32] */ &TextureCubeArray_,
- /* [33] */ &TextureMultisampled2D_,
- /* [34] */ &TextureDepth2D_,
- /* [35] */ &TextureDepth2DArray_,
- /* [36] */ &TextureDepthCube_,
- /* [37] */ &TextureDepthCubeArray_,
- /* [38] */ &TextureDepthMultisampled2D_,
- /* [39] */ &TextureStorage1D_,
- /* [40] */ &TextureStorage2D_,
- /* [41] */ &TextureStorage2DArray_,
- /* [42] */ &TextureStorage3D_,
- /* [43] */ &TextureExternal_,
- /* [44] */ &ModfResult_,
- /* [45] */ &ModfResultVec_,
- /* [46] */ &FrexpResult_,
- /* [47] */ &FrexpResultVec_,
- /* [48] */ &AtomicCompareExchangeResult_,
- /* [49] */ &Fiu32_,
- /* [50] */ &Fi32_,
- /* [51] */ &Iu32_,
- /* [52] */ &Scalar_,
- /* [53] */ &AbstractOrScalar_,
- /* [54] */ &AfF32_,
- /* [55] */ &ScalarNoF32_,
- /* [56] */ &ScalarNoI32_,
- /* [57] */ &ScalarNoU32_,
- /* [58] */ &ScalarNoBool_,
+ /* [8] */ &F16_,
+ /* [9] */ &Vec2_,
+ /* [10] */ &Vec3_,
+ /* [11] */ &Vec4_,
+ /* [12] */ &Mat2X2_,
+ /* [13] */ &Mat2X3_,
+ /* [14] */ &Mat2X4_,
+ /* [15] */ &Mat3X2_,
+ /* [16] */ &Mat3X3_,
+ /* [17] */ &Mat3X4_,
+ /* [18] */ &Mat4X2_,
+ /* [19] */ &Mat4X3_,
+ /* [20] */ &Mat4X4_,
+ /* [21] */ &Vec_,
+ /* [22] */ &Mat_,
+ /* [23] */ &Ptr_,
+ /* [24] */ &Atomic_,
+ /* [25] */ &Array_,
+ /* [26] */ &Sampler_,
+ /* [27] */ &SamplerComparison_,
+ /* [28] */ &Texture1D_,
+ /* [29] */ &Texture2D_,
+ /* [30] */ &Texture2DArray_,
+ /* [31] */ &Texture3D_,
+ /* [32] */ &TextureCube_,
+ /* [33] */ &TextureCubeArray_,
+ /* [34] */ &TextureMultisampled2D_,
+ /* [35] */ &TextureDepth2D_,
+ /* [36] */ &TextureDepth2DArray_,
+ /* [37] */ &TextureDepthCube_,
+ /* [38] */ &TextureDepthCubeArray_,
+ /* [39] */ &TextureDepthMultisampled2D_,
+ /* [40] */ &TextureStorage1D_,
+ /* [41] */ &TextureStorage2D_,
+ /* [42] */ &TextureStorage2DArray_,
+ /* [43] */ &TextureStorage3D_,
+ /* [44] */ &TextureExternal_,
+ /* [45] */ &ModfResult_,
+ /* [46] */ &ModfResultVec_,
+ /* [47] */ &FrexpResult_,
+ /* [48] */ &FrexpResultVec_,
+ /* [49] */ &AtomicCompareExchangeResult_,
+ /* [50] */ &F32F16_,
+ /* [51] */ &Fiu32_,
+ /* [52] */ &Fi32_,
+ /* [53] */ &Iu32_,
+ /* [54] */ &Scalar_,
+ /* [55] */ &AbstractOrScalar_,
+ /* [56] */ &AfF32_,
+ /* [57] */ &AfF32F16_,
+ /* [58] */ &ScalarNoF32_,
+ /* [59] */ &ScalarNoF16_,
+ /* [60] */ &ScalarNoI32_,
+ /* [61] */ &ScalarNoU32_,
+ /* [62] */ &ScalarNoBool_,
};
/// The template numbers, and number matchers
@@ -2350,209 +2517,232 @@
Matchers::~Matchers() = default;
constexpr MatcherIndex kMatcherIndices[] = {
- /* [0] */ 22,
+ /* [0] */ 23,
/* [1] */ 0,
- /* [2] */ 23,
+ /* [2] */ 24,
/* [3] */ 0,
/* [4] */ 11,
- /* [5] */ 7,
- /* [6] */ 22,
+ /* [5] */ 0,
+ /* [6] */ 23,
/* [7] */ 9,
- /* [8] */ 24,
+ /* [8] */ 25,
/* [9] */ 0,
/* [10] */ 0,
- /* [11] */ 21,
+ /* [11] */ 22,
/* [12] */ 0,
/* [13] */ 1,
/* [14] */ 7,
- /* [15] */ 21,
+ /* [15] */ 22,
/* [16] */ 0,
- /* [17] */ 0,
+ /* [17] */ 2,
/* [18] */ 7,
- /* [19] */ 21,
- /* [20] */ 0,
- /* [21] */ 2,
+ /* [19] */ 22,
+ /* [20] */ 1,
+ /* [21] */ 0,
/* [22] */ 7,
- /* [23] */ 21,
+ /* [23] */ 22,
/* [24] */ 1,
- /* [25] */ 0,
+ /* [25] */ 2,
/* [26] */ 7,
- /* [27] */ 21,
- /* [28] */ 1,
- /* [29] */ 2,
+ /* [27] */ 22,
+ /* [28] */ 0,
+ /* [29] */ 0,
/* [30] */ 7,
- /* [31] */ 20,
+ /* [31] */ 21,
/* [32] */ 0,
- /* [33] */ 7,
- /* [34] */ 41,
+ /* [33] */ 0,
+ /* [34] */ 21,
/* [35] */ 0,
- /* [36] */ 1,
- /* [37] */ 20,
- /* [38] */ 0,
- /* [39] */ 0,
- /* [40] */ 42,
- /* [41] */ 5,
- /* [42] */ 10,
- /* [43] */ 7,
- /* [44] */ 20,
- /* [45] */ 0,
- /* [46] */ 2,
- /* [47] */ 41,
- /* [48] */ 5,
- /* [49] */ 10,
- /* [50] */ 0,
- /* [51] */ 40,
- /* [52] */ 5,
- /* [53] */ 10,
- /* [54] */ 1,
- /* [55] */ 39,
- /* [56] */ 5,
- /* [57] */ 10,
- /* [58] */ 5,
- /* [59] */ 42,
- /* [60] */ 4,
- /* [61] */ 10,
- /* [62] */ 6,
- /* [63] */ 41,
+ /* [36] */ 7,
+ /* [37] */ 43,
+ /* [38] */ 5,
+ /* [39] */ 10,
+ /* [40] */ 7,
+ /* [41] */ 42,
+ /* [42] */ 5,
+ /* [43] */ 10,
+ /* [44] */ 2,
+ /* [45] */ 21,
+ /* [46] */ 0,
+ /* [47] */ 2,
+ /* [48] */ 41,
+ /* [49] */ 5,
+ /* [50] */ 10,
+ /* [51] */ 1,
+ /* [52] */ 40,
+ /* [53] */ 5,
+ /* [54] */ 10,
+ /* [55] */ 6,
+ /* [56] */ 43,
+ /* [57] */ 4,
+ /* [58] */ 10,
+ /* [59] */ 5,
+ /* [60] */ 42,
+ /* [61] */ 0,
+ /* [62] */ 1,
+ /* [63] */ 42,
/* [64] */ 4,
/* [65] */ 10,
- /* [66] */ 2,
- /* [67] */ 40,
+ /* [66] */ 8,
+ /* [67] */ 41,
/* [68] */ 4,
/* [69] */ 10,
- /* [70] */ 39,
- /* [71] */ 4,
- /* [72] */ 10,
- /* [73] */ 42,
- /* [74] */ 3,
- /* [75] */ 10,
- /* [76] */ 20,
- /* [77] */ 1,
- /* [78] */ 7,
- /* [79] */ 41,
- /* [80] */ 3,
- /* [81] */ 10,
- /* [82] */ 40,
- /* [83] */ 3,
- /* [84] */ 10,
- /* [85] */ 42,
- /* [86] */ 0,
- /* [87] */ 1,
- /* [88] */ 40,
- /* [89] */ 0,
- /* [90] */ 1,
- /* [91] */ 39,
- /* [92] */ 0,
- /* [93] */ 1,
- /* [94] */ 20,
- /* [95] */ 0,
- /* [96] */ 5,
- /* [97] */ 39,
- /* [98] */ 3,
- /* [99] */ 10,
- /* [100] */ 20,
- /* [101] */ 0,
- /* [102] */ 6,
- /* [103] */ 28,
- /* [104] */ 7,
- /* [105] */ 8,
- /* [106] */ 0,
- /* [107] */ 8,
- /* [108] */ 1,
- /* [109] */ 8,
- /* [110] */ 7,
- /* [111] */ 8,
- /* [112] */ 5,
- /* [113] */ 8,
- /* [114] */ 6,
- /* [115] */ 8,
- /* [116] */ 2,
- /* [117] */ 9,
- /* [118] */ 0,
- /* [119] */ 45,
- /* [120] */ 0,
- /* [121] */ 9,
- /* [122] */ 1,
- /* [123] */ 9,
- /* [124] */ 7,
- /* [125] */ 9,
- /* [126] */ 5,
- /* [127] */ 9,
- /* [128] */ 6,
- /* [129] */ 9,
- /* [130] */ 2,
- /* [131] */ 30,
- /* [132] */ 0,
- /* [133] */ 27,
- /* [134] */ 0,
- /* [135] */ 28,
- /* [136] */ 0,
- /* [137] */ 29,
- /* [138] */ 0,
- /* [139] */ 31,
- /* [140] */ 0,
- /* [141] */ 32,
- /* [142] */ 0,
- /* [143] */ 33,
- /* [144] */ 0,
- /* [145] */ 47,
- /* [146] */ 0,
- /* [147] */ 11,
- /* [148] */ 0,
- /* [149] */ 12,
- /* [150] */ 7,
- /* [151] */ 12,
- /* [152] */ 0,
- /* [153] */ 13,
- /* [154] */ 7,
- /* [155] */ 13,
- /* [156] */ 0,
- /* [157] */ 14,
- /* [158] */ 7,
- /* [159] */ 14,
- /* [160] */ 0,
- /* [161] */ 15,
- /* [162] */ 7,
- /* [163] */ 15,
- /* [164] */ 0,
- /* [165] */ 16,
- /* [166] */ 7,
- /* [167] */ 16,
- /* [168] */ 0,
- /* [169] */ 17,
- /* [170] */ 7,
- /* [171] */ 17,
- /* [172] */ 0,
- /* [173] */ 48,
- /* [174] */ 0,
- /* [175] */ 18,
- /* [176] */ 7,
- /* [177] */ 18,
- /* [178] */ 0,
- /* [179] */ 27,
- /* [180] */ 7,
- /* [181] */ 29,
- /* [182] */ 7,
- /* [183] */ 30,
- /* [184] */ 7,
- /* [185] */ 31,
- /* [186] */ 7,
- /* [187] */ 32,
- /* [188] */ 7,
- /* [189] */ 19,
- /* [190] */ 7,
- /* [191] */ 19,
- /* [192] */ 0,
- /* [193] */ 25,
- /* [194] */ 26,
- /* [195] */ 37,
- /* [196] */ 36,
- /* [197] */ 35,
- /* [198] */ 34,
- /* [199] */ 43,
- /* [200] */ 38,
- /* [201] */ 44,
- /* [202] */ 46,
+ /* [70] */ 0,
+ /* [71] */ 40,
+ /* [72] */ 4,
+ /* [73] */ 10,
+ /* [74] */ 43,
+ /* [75] */ 3,
+ /* [76] */ 10,
+ /* [77] */ 21,
+ /* [78] */ 1,
+ /* [79] */ 7,
+ /* [80] */ 42,
+ /* [81] */ 3,
+ /* [82] */ 10,
+ /* [83] */ 41,
+ /* [84] */ 3,
+ /* [85] */ 10,
+ /* [86] */ 43,
+ /* [87] */ 0,
+ /* [88] */ 1,
+ /* [89] */ 41,
+ /* [90] */ 0,
+ /* [91] */ 1,
+ /* [92] */ 40,
+ /* [93] */ 0,
+ /* [94] */ 1,
+ /* [95] */ 21,
+ /* [96] */ 0,
+ /* [97] */ 5,
+ /* [98] */ 21,
+ /* [99] */ 0,
+ /* [100] */ 6,
+ /* [101] */ 40,
+ /* [102] */ 3,
+ /* [103] */ 10,
+ /* [104] */ 9,
+ /* [105] */ 0,
+ /* [106] */ 11,
+ /* [107] */ 7,
+ /* [108] */ 9,
+ /* [109] */ 7,
+ /* [110] */ 9,
+ /* [111] */ 2,
+ /* [112] */ 9,
+ /* [113] */ 1,
+ /* [114] */ 46,
+ /* [115] */ 0,
+ /* [116] */ 11,
+ /* [117] */ 1,
+ /* [118] */ 9,
+ /* [119] */ 6,
+ /* [120] */ 11,
+ /* [121] */ 8,
+ /* [122] */ 9,
+ /* [123] */ 5,
+ /* [124] */ 9,
+ /* [125] */ 8,
+ /* [126] */ 28,
+ /* [127] */ 0,
+ /* [128] */ 29,
+ /* [129] */ 0,
+ /* [130] */ 30,
+ /* [131] */ 0,
+ /* [132] */ 31,
+ /* [133] */ 0,
+ /* [134] */ 32,
+ /* [135] */ 0,
+ /* [136] */ 11,
+ /* [137] */ 5,
+ /* [138] */ 33,
+ /* [139] */ 0,
+ /* [140] */ 34,
+ /* [141] */ 0,
+ /* [142] */ 11,
+ /* [143] */ 6,
+ /* [144] */ 11,
+ /* [145] */ 2,
+ /* [146] */ 12,
+ /* [147] */ 0,
+ /* [148] */ 12,
+ /* [149] */ 7,
+ /* [150] */ 12,
+ /* [151] */ 8,
+ /* [152] */ 13,
+ /* [153] */ 0,
+ /* [154] */ 20,
+ /* [155] */ 7,
+ /* [156] */ 13,
+ /* [157] */ 7,
+ /* [158] */ 13,
+ /* [159] */ 8,
+ /* [160] */ 14,
+ /* [161] */ 0,
+ /* [162] */ 48,
+ /* [163] */ 0,
+ /* [164] */ 14,
+ /* [165] */ 7,
+ /* [166] */ 14,
+ /* [167] */ 8,
+ /* [168] */ 15,
+ /* [169] */ 0,
+ /* [170] */ 15,
+ /* [171] */ 7,
+ /* [172] */ 15,
+ /* [173] */ 8,
+ /* [174] */ 16,
+ /* [175] */ 0,
+ /* [176] */ 16,
+ /* [177] */ 7,
+ /* [178] */ 16,
+ /* [179] */ 8,
+ /* [180] */ 17,
+ /* [181] */ 0,
+ /* [182] */ 17,
+ /* [183] */ 7,
+ /* [184] */ 17,
+ /* [185] */ 8,
+ /* [186] */ 18,
+ /* [187] */ 0,
+ /* [188] */ 18,
+ /* [189] */ 7,
+ /* [190] */ 18,
+ /* [191] */ 8,
+ /* [192] */ 28,
+ /* [193] */ 7,
+ /* [194] */ 29,
+ /* [195] */ 7,
+ /* [196] */ 19,
+ /* [197] */ 0,
+ /* [198] */ 30,
+ /* [199] */ 7,
+ /* [200] */ 49,
+ /* [201] */ 0,
+ /* [202] */ 31,
+ /* [203] */ 7,
+ /* [204] */ 32,
+ /* [205] */ 7,
+ /* [206] */ 33,
+ /* [207] */ 7,
+ /* [208] */ 19,
+ /* [209] */ 7,
+ /* [210] */ 19,
+ /* [211] */ 8,
+ /* [212] */ 20,
+ /* [213] */ 0,
+ /* [214] */ 20,
+ /* [215] */ 8,
+ /* [216] */ 26,
+ /* [217] */ 27,
+ /* [218] */ 38,
+ /* [219] */ 37,
+ /* [220] */ 36,
+ /* [221] */ 35,
+ /* [222] */ 44,
+ /* [223] */ 39,
+ /* [224] */ 45,
+ /* [225] */ 47,
};
// Assert that the MatcherIndex is big enough to index all the matchers, plus
@@ -2890,1152 +3080,1152 @@
{
/* [65] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[181],
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [66] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [67] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [68] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [69] */
/* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [70] */
/* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [71] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [72] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [73] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [74] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [75] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [76] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [77] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [78] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[183],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [79] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [80] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [81] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [82] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [83] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[125],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [84] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[181],
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [85] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [86] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [87] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [88] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [89] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [90] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [91] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[137],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [92] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [93] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [94] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [95] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [96] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [97] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [98] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [99] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [100] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [101] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [102] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[187],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [103] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [104] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [105] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [106] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [107] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [108] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [109] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [110] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [111] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [112] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [113] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [114] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[181],
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [115] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [116] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [117] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [118] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [119] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[58],
},
{
/* [120] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [121] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [122] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [123] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [124] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [125] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [126] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[181],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [127] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [128] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [129] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [130] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [131] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [132] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [133] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [134] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [135] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [136] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [137] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [138] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [139] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [140] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [141] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [142] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [143] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [144] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* matcher indices */ &kMatcherIndices[206],
},
{
/* [145] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [146] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [147] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [148] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [149] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [150] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [151] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[135],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [152] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [153] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [154] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[58],
},
{
/* [155] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [156] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [157] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [158] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [159] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[58],
},
{
/* [160] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [161] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [162] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [163] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [164] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [165] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [166] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [167] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [168] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [169] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [170] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[195],
+ /* matcher indices */ &kMatcherIndices[206],
},
{
/* [171] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [172] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [173] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [174] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [175] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[206],
},
{
/* [176] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [177] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [178] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [179] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [180] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [181] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [182] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [183] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [184] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [185] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [186] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [187] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [188] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [189] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [190] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[183],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [191] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [192] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [193] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [194] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [195] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[195],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [196] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [197] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [198] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [199] */
/* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [200] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[195],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [201] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [202] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [203] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [204] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [205] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[183],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [206] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [207] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [208] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [209] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[125],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [210] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [211] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[141],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [212] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [213] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [214] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [215] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [216] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [217] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [218] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [219] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [220] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[181],
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [221] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [222] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [223] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [224] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [225] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [226] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [227] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [228] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [229] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [230] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[185],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [231] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [232] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [233] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [234] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [235] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[187],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [236] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [237] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [238] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [239] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [240] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [241] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [242] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [243] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [244] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [245] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[181],
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [246] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [247] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [248] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [249] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [250] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[181],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [251] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [252] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [253] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [254] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [255] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [256] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[137],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [257] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [258] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [259] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [260] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [261] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [262] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [263] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [264] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [265] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[195],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [266] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [267] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [268] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [269] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [270] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [271] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [272] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [273] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [274] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [275] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[187],
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [276] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [277] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [278] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [279] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [280] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [281] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [282] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [283] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [284] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [285] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* matcher indices */ &kMatcherIndices[204],
},
{
/* [286] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [287] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [288] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [289] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [290] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[183],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [291] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [292] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [293] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [294] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[125],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [295] */
@@ -4045,637 +4235,637 @@
{
/* [296] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [297] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [298] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [299] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[185],
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [300] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [301] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [302] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [303] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[196],
+ /* matcher indices */ &kMatcherIndices[219],
},
{
/* [304] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [305] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [306] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [307] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[183],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [308] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [309] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [310] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [311] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[181],
+ /* matcher indices */ &kMatcherIndices[219],
},
{
/* [312] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [313] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [314] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [315] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [316] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [317] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [318] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [319] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[195],
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [320] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [321] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [322] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[58],
},
{
/* [323] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* matcher indices */ &kMatcherIndices[206],
},
{
/* [324] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [325] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [326] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [327] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[79],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [328] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [329] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [330] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[42],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [331] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [332] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [333] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [334] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [335] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [336] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [337] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [338] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [339] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[187],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [340] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [341] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [342] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [343] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[183],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [344] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [345] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [346] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[125],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [347] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[63],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [348] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [349] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [350] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[57],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [351] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[49],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [352] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[49],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [353] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[49],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [354] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[49],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [355] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[183],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [356] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [357] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [358] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [359] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[185],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [360] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [361] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [362] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [363] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [364] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [365] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [366] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [367] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[47],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [368] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [369] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [370] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[61],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [371] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[196],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [372] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [373] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [374] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [375] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[137],
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [376] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [377] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [378] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [379] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [380] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [381] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [382] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [383] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[196],
+ /* matcher indices */ &kMatcherIndices[204],
},
{
/* [384] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [385] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [386] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [387] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[204],
},
{
/* [388] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [389] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [390] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [391] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[195],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [392] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [393] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [394] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [395] */
- /* usage */ ParameterUsage::kX,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [396] */
- /* usage */ ParameterUsage::kY,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [397] */
- /* usage */ ParameterUsage::kZ,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [398] */
- /* usage */ ParameterUsage::kW,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [399] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [400] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [401] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [402] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [403] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [404] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [405] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [406] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [407] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[219],
},
{
/* [408] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [409] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [410] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [411] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [412] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [413] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [414] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [415] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[196],
+ /* matcher indices */ &kMatcherIndices[80],
},
{
/* [416] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [417] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [418] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [419] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[63],
},
{
/* [420] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [421] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [422] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[136],
},
{
/* [423] */
@@ -4690,202 +4880,202 @@
{
/* [425] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [426] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [427] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[105],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [428] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[105],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [429] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[105],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [430] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[105],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [431] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[41],
},
{
/* [432] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[194],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [433] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [434] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [435] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [436] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [437] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [438] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [439] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kX,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [440] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kY,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [441] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kZ,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [442] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kW,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [443] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[219],
},
{
/* [444] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[135],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[217],
},
{
/* [445] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [446] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [447] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [448] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [449] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kSampleIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [450] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [451] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [452] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [453] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[71],
},
{
/* [454] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [455] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[136],
},
{
/* [456] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [457] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [458] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [459] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [460] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [461] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [462] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [463] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [464] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [465] */
@@ -4900,897 +5090,897 @@
{
/* [467] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [468] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[219],
},
{
/* [469] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [470] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [471] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[199],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [472] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kY,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [473] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kZw,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [474] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[196],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [475] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kYz,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [476] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kW,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [477] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[97],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [478] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [479] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[42],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [480] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[82],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [481] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [482] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[42],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [483] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[73],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [484] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[125],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [485] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[42],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [486] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* usage */ ParameterUsage::kXy,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [487] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kZ,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [488] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kW,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [489] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[70],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [490] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [491] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[57],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [492] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[185],
+ /* matcher indices */ &kMatcherIndices[204],
},
{
/* [493] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [494] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [495] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[67],
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [496] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [497] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[57],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [498] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[183],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [499] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kY,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [500] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kZ,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [501] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[59],
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [502] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[125],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [503] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[57],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [504] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[55],
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [505] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [506] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[61],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [507] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[219],
},
{
/* [508] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
+ },
+ {
+ /* [509] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[39],
+ },
+ {
+ /* [510] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [511] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [512] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[17],
+ },
+ {
+ /* [513] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [514] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[55],
+ },
+ {
+ /* [515] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[55],
+ },
+ {
+ /* [516] */
/* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[31],
},
{
- /* [509] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
- },
- {
- /* [510] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[51],
- },
- {
- /* [511] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
- },
- {
- /* [512] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[61],
- },
- {
- /* [513] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
- },
- {
- /* [514] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
- },
- {
- /* [515] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
- },
- {
- /* [516] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[179],
- },
- {
/* [517] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [518] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [519] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[40],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [520] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[125],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [521] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[61],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [522] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [523] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [524] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [525] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [526] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [527] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [528] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [529] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [530] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[44],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [531] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [532] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [533] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [534] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[135],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [535] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [536] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [537] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[143],
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [538] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [539] */
- /* usage */ ParameterUsage::kSampleIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [540] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[101],
},
{
/* [541] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [542] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [543] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[200],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [544] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [545] */
- /* usage */ ParameterUsage::kSampleIndex,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [546] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [547] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [548] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [549] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[83],
},
{
/* [550] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [551] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [552] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[74],
},
{
/* [553] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[58],
},
{
/* [554] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [555] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[196],
+ /* matcher indices */ &kMatcherIndices[67],
},
{
/* [556] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [557] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[136],
},
{
/* [558] */
- /* usage */ ParameterUsage::kX,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[56],
},
{
/* [559] */
- /* usage */ ParameterUsage::kY,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[58],
},
{
/* [560] */
- /* usage */ ParameterUsage::kZ,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[136],
},
{
/* [561] */
- /* usage */ ParameterUsage::kXy,
- /* matcher indices */ &kMatcherIndices[105],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[52],
},
{
/* [562] */
- /* usage */ ParameterUsage::kZ,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [563] */
- /* usage */ ParameterUsage::kW,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [564] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[48],
},
{
/* [565] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [566] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [567] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [568] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[193],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [569] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [570] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [571] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [572] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [573] */
- /* usage */ ParameterUsage::kX,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [574] */
- /* usage */ ParameterUsage::kY,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[58],
},
{
/* [575] */
- /* usage */ ParameterUsage::kZw,
- /* matcher indices */ &kMatcherIndices[105],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[142],
},
{
/* [576] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[105],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[223],
},
{
/* [577] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[105],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [578] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[105],
+ /* usage */ ParameterUsage::kSampleIndex,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [579] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [580] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [581] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [582] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[49],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [583] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[49],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [584] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[49],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [585] */
- /* usage */ ParameterUsage::kX,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [586] */
- /* usage */ ParameterUsage::kYz,
- /* matcher indices */ &kMatcherIndices[105],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[58],
},
{
/* [587] */
- /* usage */ ParameterUsage::kW,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [588] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [589] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[125],
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [590] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [591] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [592] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [593] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[49],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [594] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[49],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [595] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[117],
+ /* matcher indices */ &kMatcherIndices[77],
},
{
/* [596] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[117],
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [597] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [598] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [599] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[105],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [600] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[105],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [601] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [602] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[122],
},
{
/* [603] */
- /* usage */ ParameterUsage::kX,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[15],
},
{
/* [604] */
- /* usage */ ParameterUsage::kZyw,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[19],
},
{
/* [605] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [606] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [607] */
- /* usage */ ParameterUsage::kXyz,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [608] */
- /* usage */ ParameterUsage::kW,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [609] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[135],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [610] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
- },
- {
- /* [611] */
- /* usage */ ParameterUsage::kXy,
- /* matcher indices */ &kMatcherIndices[105],
- },
- {
- /* [612] */
- /* usage */ ParameterUsage::kZw,
- /* matcher indices */ &kMatcherIndices[105],
- },
- {
- /* [613] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[137],
- },
- {
- /* [614] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
- },
- {
- /* [615] */
- /* usage */ ParameterUsage::kX,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
{
+ /* [611] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [612] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [613] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
+ },
+ {
+ /* [614] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [615] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
+ },
+ {
/* [616] */
- /* usage */ ParameterUsage::kYz,
- /* matcher indices */ &kMatcherIndices[105],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [617] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [618] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [619] */
- /* usage */ ParameterUsage::kXy,
- /* matcher indices */ &kMatcherIndices[105],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [620] */
- /* usage */ ParameterUsage::kZ,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [621] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [622] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [623] */
- /* usage */ ParameterUsage::kX,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [624] */
- /* usage */ ParameterUsage::kY,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [625] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[141],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [626] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [627] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [628] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[100],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [629] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [630] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [631] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [632] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[95],
},
{
/* [633] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [634] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[100],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [635] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [636] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
- },
- {
- /* [637] */
/* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
{
+ /* [637] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[138],
+ },
+ {
/* [638] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [639] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[196],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [640] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [641] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [642] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [643] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[195],
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [644] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [645] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [646] */
@@ -5799,38 +5989,38 @@
},
{
/* [647] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [648] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [649] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [650] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [651] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[219],
},
{
/* [652] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [653] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [654] */
@@ -5839,13 +6029,13 @@
},
{
/* [655] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [656] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [657] */
@@ -5855,167 +6045,167 @@
{
/* [658] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [659] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [660] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [661] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [662] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [663] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [664] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [665] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [666] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [667] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [668] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [669] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [670] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [671] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [672] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [673] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [674] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [675] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [676] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [677] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [678] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [679] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[44],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [680] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[44],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [681] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [682] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [683] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [684] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [685] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [686] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [687] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[44],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [688] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[44],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [689] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [690] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [691] */
@@ -6030,32 +6220,32 @@
{
/* [693] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [694] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [695] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [696] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [697] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [698] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [699] */
@@ -6070,17 +6260,17 @@
{
/* [701] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [702] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [703] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [704] */
@@ -6090,12 +6280,12 @@
{
/* [705] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [706] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [707] */
@@ -6110,27 +6300,27 @@
{
/* [709] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[19],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [710] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[23],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [711] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[76],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [712] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[11],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [713] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[11],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [714] */
@@ -6140,92 +6330,92 @@
{
/* [715] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[11],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [716] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [717] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [718] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[11],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [719] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [720] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [721] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [722] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [723] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [724] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [725] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [726] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [727] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[11],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [728] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[11],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [729] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [730] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [731] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [732] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [733] */
@@ -6235,182 +6425,182 @@
{
/* [734] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[98],
},
{
/* [735] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [736] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [737] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [738] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[39],
},
{
/* [739] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [740] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [741] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [742] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [743] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[11],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [744] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[11],
+ /* matcher indices */ &kMatcherIndices[98],
},
{
/* [745] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kX,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [746] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kY,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [747] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [748] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [749] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [750] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
- },
- {
- /* [751] */
- /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
{
+ /* [751] */
+ /* usage */ ParameterUsage::kXy,
+ /* matcher indices */ &kMatcherIndices[104],
+ },
+ {
/* [752] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kZ,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [753] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [754] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [755] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [756] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kYz,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [757] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [758] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [759] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [760] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [761] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [762] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [763] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [764] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [765] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [766] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [767] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* usage */ ParameterUsage::kXy,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [768] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kZw,
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [769] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [770] */
@@ -6420,97 +6610,97 @@
{
/* [771] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [772] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [773] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* usage */ ParameterUsage::kXyz,
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [774] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kW,
/* matcher indices */ &kMatcherIndices[1],
},
{
/* [775] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [776] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kZyw,
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [777] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [778] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [779] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [780] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[94],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [781] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [782] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [783] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[199],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [784] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [785] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [786] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [787] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [788] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [789] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [790] */
@@ -6520,317 +6710,317 @@
{
/* [791] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [792] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [793] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [794] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [795] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [796] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [797] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[223],
},
{
/* [798] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [799] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [800] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[219],
},
{
/* [801] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [802] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [803] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [804] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [805] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [806] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [807] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [808] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [809] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [810] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [811] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [812] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [813] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [814] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [815] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[86],
},
{
/* [816] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[60],
},
{
/* [817] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[89],
},
{
/* [818] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[92],
},
{
/* [819] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[223],
},
{
/* [820] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [821] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[219],
},
{
/* [822] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [823] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[221],
},
{
/* [824] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[140],
},
{
/* [825] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[138],
},
{
/* [826] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[134],
},
{
/* [827] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[132],
},
{
/* [828] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [829] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [830] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [831] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[154],
},
{
/* [832] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [833] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [834] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [835] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[85],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [836] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [837] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [838] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [839] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [840] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [841] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [842] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [843] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [844] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [845] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [846] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [847] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [848] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [849] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [850] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [851] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [852] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [853] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[44],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [854] */
@@ -6840,212 +7030,212 @@
{
/* [855] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [856] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [857] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [858] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [859] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [860] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [861] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[42],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [862] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[42],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [863] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [864] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [865] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [866] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [867] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [868] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[200],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[106],
},
{
/* [869] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [870] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[195],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [871] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[196],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [872] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
- },
- {
- /* [873] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
- },
- {
- /* [874] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[141],
- },
- {
- /* [875] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
- },
- {
- /* [876] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
- },
- {
- /* [877] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[137],
- },
- {
- /* [878] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[135],
- },
- {
- /* [879] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
- },
- {
- /* [880] */
- /* usage */ ParameterUsage::kTexture,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[34],
},
{
+ /* [873] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
+ },
+ {
+ /* [874] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
+ },
+ {
+ /* [875] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
+ },
+ {
+ /* [876] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
+ },
+ {
+ /* [877] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
+ },
+ {
+ /* [878] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
+ },
+ {
+ /* [879] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
+ },
+ {
+ /* [880] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
+ },
+ {
/* [881] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[195],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [882] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [883] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[141],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [884] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[137],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [885] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [886] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [887] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [888] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [889] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [890] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [891] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [892] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [893] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [894] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [895] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [896] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [897] */
@@ -7055,117 +7245,117 @@
{
/* [898] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [899] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [900] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[11],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [901] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [902] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[199],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [903] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [904] */
- /* usage */ ParameterUsage::kTexture,
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[34],
},
{
/* [905] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[88],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [906] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[91],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [907] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[200],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [908] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[195],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [909] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[196],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [910] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[197],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [911] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[198],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [912] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [913] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[189],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [914] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[41],
+ /* matcher indices */ &kMatcherIndices[184],
},
{
/* [915] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[27],
},
{
/* [916] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [917] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [918] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [919] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [920] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [921] */
@@ -7180,7 +7370,7 @@
{
/* [923] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [924] */
@@ -7190,12 +7380,12 @@
{
/* [925] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[175],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [926] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[105],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [927] */
@@ -7204,88 +7394,88 @@
},
{
/* [928] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[141],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [929] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[107],
+ /* matcher indices */ &kMatcherIndices[66],
},
{
/* [930] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[107],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [931] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[107],
+ /* matcher indices */ &kMatcherIndices[208],
},
{
/* [932] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[107],
+ /* matcher indices */ &kMatcherIndices[17],
},
{
/* [933] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [934] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[117],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [935] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[104],
},
{
/* [936] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [937] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [938] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [939] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[121],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [940] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[121],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [941] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[121],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [942] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[121],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [943] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[44],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [944] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[49],
+ /* matcher indices */ &kMatcherIndices[69],
},
{
/* [945] */
@@ -7300,7 +7490,7 @@
{
/* [947] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [948] */
@@ -7310,42 +7500,42 @@
{
/* [949] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[50],
},
{
/* [950] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[137],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[50],
},
{
/* [951] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[135],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[50],
},
{
/* [952] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[50],
},
{
/* [953] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[53],
+ /* matcher indices */ &kMatcherIndices[50],
},
{
/* [954] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[53],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [955] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[53],
+ /* matcher indices */ &kMatcherIndices[4],
},
{
/* [956] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[53],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [957] */
@@ -7355,133 +7545,278 @@
{
/* [958] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[4],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [959] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [960] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[37],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [961] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [962] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[169],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [963] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[149],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [964] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [965] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [966] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [967] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[21],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [968] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[153],
+ /* matcher indices */ &kMatcherIndices[116],
},
{
/* [969] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [970] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[146],
},
{
/* [971] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[62],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [972] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[44],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [973] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[157],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [974] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[148],
},
{
/* [975] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[150],
},
{
/* [976] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[31],
+ /* matcher indices */ &kMatcherIndices[190],
},
{
/* [977] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[152],
},
{
/* [978] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[161],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [979] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[34],
},
{
/* [980] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[5],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [981] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[6],
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [982] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[165],
+ /* matcher indices */ &kMatcherIndices[158],
},
{
/* [983] */
/* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[188],
+ },
+ {
+ /* [984] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[160],
+ },
+ {
+ /* [985] */
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[1],
},
+ {
+ /* [986] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
+ },
+ {
+ /* [987] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
+ },
+ {
+ /* [988] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[164],
+ },
+ {
+ /* [989] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[166],
+ },
+ {
+ /* [990] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
+ },
+ {
+ /* [991] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[168],
+ },
+ {
+ /* [992] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [993] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
+ },
+ {
+ /* [994] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
+ },
+ {
+ /* [995] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[170],
+ },
+ {
+ /* [996] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[172],
+ },
+ {
+ /* [997] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[17],
+ },
+ {
+ /* [998] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[174],
+ },
+ {
+ /* [999] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [1000] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[6],
+ },
+ {
+ /* [1001] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[45],
+ },
+ {
+ /* [1002] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[176],
+ },
+ {
+ /* [1003] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[178],
+ },
+ {
+ /* [1004] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [1005] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[180],
+ },
+ {
+ /* [1006] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [1007] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[17],
+ },
+ {
+ /* [1008] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[45],
+ },
+ {
+ /* [1009] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[182],
+ },
+ {
+ /* [1010] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[14],
+ },
+ {
+ /* [1011] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[186],
+ },
+ {
+ /* [1012] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[34],
+ },
};
constexpr TemplateTypeInfo kTemplateTypes[] = {
@@ -7493,7 +7828,7 @@
{
/* [1] */
/* name */ "U",
- /* matcher index */ 58,
+ /* matcher index */ 62,
},
{
/* [2] */
@@ -7503,87 +7838,107 @@
{
/* [3] */
/* name */ "U",
- /* matcher index */ 55,
+ /* matcher index */ 58,
},
{
/* [4] */
/* name */ "T",
- /* matcher index */ 5,
+ /* matcher index */ 8,
},
{
/* [5] */
/* name */ "U",
- /* matcher index */ 56,
+ /* matcher index */ 59,
},
{
/* [6] */
/* name */ "T",
- /* matcher index */ 6,
+ /* matcher index */ 5,
},
{
/* [7] */
/* name */ "U",
- /* matcher index */ 57,
+ /* matcher index */ 60,
},
{
/* [8] */
/* name */ "T",
- /* matcher index */ 49,
+ /* matcher index */ 6,
},
{
/* [9] */
- /* name */ "f32",
- /* matcher index */ kNoMatcher,
+ /* name */ "U",
+ /* matcher index */ 61,
},
{
/* [10] */
/* name */ "T",
- /* matcher index */ 54,
+ /* matcher index */ 53,
},
{
/* [11] */
/* name */ "T",
- /* matcher index */ 51,
+ /* matcher index */ 57,
},
{
/* [12] */
/* name */ "T",
- /* matcher index */ 53,
+ /* matcher index */ 56,
},
{
/* [13] */
/* name */ "T",
- /* matcher index */ 52,
+ /* matcher index */ 50,
},
{
/* [14] */
/* name */ "T",
- /* matcher index */ kNoMatcher,
+ /* matcher index */ 51,
},
{
/* [15] */
/* name */ "T",
- /* matcher index */ 58,
+ /* matcher index */ 55,
},
{
/* [16] */
/* name */ "T",
- /* matcher index */ 55,
+ /* matcher index */ 54,
},
{
/* [17] */
/* name */ "T",
- /* matcher index */ 57,
+ /* matcher index */ kNoMatcher,
},
{
/* [18] */
/* name */ "T",
- /* matcher index */ 56,
+ /* matcher index */ 59,
},
{
/* [19] */
/* name */ "T",
- /* matcher index */ 50,
+ /* matcher index */ 62,
+ },
+ {
+ /* [20] */
+ /* name */ "T",
+ /* matcher index */ 58,
+ },
+ {
+ /* [21] */
+ /* name */ "T",
+ /* matcher index */ 61,
+ },
+ {
+ /* [22] */
+ /* name */ "T",
+ /* matcher index */ 60,
+ },
+ {
+ /* [23] */
+ /* name */ "T",
+ /* matcher index */ 52,
},
};
@@ -7646,10 +8001,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[952],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[830],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7658,10 +8013,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[605],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[617],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7670,10 +8025,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[951],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[829],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7682,10 +8037,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[609],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[621],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7694,10 +8049,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[950],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[828],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7706,10 +8061,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[613],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[625],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7718,10 +8073,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[938],
- /* return matcher indices */ &kMatcherIndices[125],
+ /* parameters */ &kParameters[827],
+ /* return matcher indices */ &kMatcherIndices[58],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7730,10 +8085,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[617],
- /* return matcher indices */ &kMatcherIndices[125],
+ /* parameters */ &kParameters[629],
+ /* return matcher indices */ &kMatcherIndices[58],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7742,10 +8097,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[937],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[826],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7754,10 +8109,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[621],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[633],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7766,10 +8121,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[928],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[825],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7778,10 +8133,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[625],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[637],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7790,10 +8145,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[912],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[824],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7802,10 +8157,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[911],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[823],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7814,10 +8169,10 @@
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[631],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[643],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7826,10 +8181,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[910],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[822],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7838,10 +8193,10 @@
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[635],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[647],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7850,10 +8205,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[909],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[821],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7862,10 +8217,10 @@
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[639],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[651],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7874,10 +8229,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[908],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[820],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7886,10 +8241,10 @@
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[643],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[655],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7898,10 +8253,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[907],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[819],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7910,10 +8265,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[3],
- /* parameters */ &kParameters[906],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[818],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7922,10 +8277,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[3],
- /* parameters */ &kParameters[905],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[817],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7934,10 +8289,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[3],
- /* parameters */ &kParameters[904],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[816],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7946,10 +8301,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[3],
- /* parameters */ &kParameters[835],
- /* return matcher indices */ &kMatcherIndices[125],
+ /* parameters */ &kParameters[815],
+ /* return matcher indices */ &kMatcherIndices[58],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -7958,263 +8313,263 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[902],
- /* return matcher indices */ &kMatcherIndices[111],
+ /* parameters */ &kParameters[814],
+ /* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [27] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[516],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [28] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[513],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[955],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [29] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[363],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[956],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [30] */
/* num parameters */ 4,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[311],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[439],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [31] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[220],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[486],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [32] */
/* num parameters */ 3,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[498],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[474],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [33] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[343],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[471],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [34] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[492],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[767],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [35] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[339],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[773],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [36] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[486],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[775],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [37] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[331],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[964],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [38] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[323],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[965],
+ /* return matcher indices */ &kMatcherIndices[120],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [39] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[6],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[285],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[966],
+ /* return matcher indices */ &kMatcherIndices[136],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [40] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[8],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[474],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[967],
+ /* return matcher indices */ &kMatcherIndices[142],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [41] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[319],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[968],
+ /* return matcher indices */ &kMatcherIndices[144],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [42] */
- /* num parameters */ 4,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[335],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[504],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [43] */
- /* num parameters */ 5,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[240],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[501],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [44] */
- /* num parameters */ 5,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[245],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[315],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [45] */
- /* num parameters */ 6,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[114],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[295],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [46] */
- /* num parameters */ 4,
+ /* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[307],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[210],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [47] */
- /* num parameters */ 5,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[205],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[495],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -8222,23 +8577,23 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[299],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[319],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [49] */
- /* num parameters */ 5,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[235],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[492],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -8246,274 +8601,274 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[295],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[323],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [51] */
- /* num parameters */ 5,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[225],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[489],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [52] */
- /* num parameters */ 5,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[280],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[335],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [53] */
- /* num parameters */ 6,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[132],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[347],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [54] */
- /* num parameters */ 4,
+ /* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[303],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[180],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [55] */
- /* num parameters */ 5,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[265],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[468],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [56] */
- /* num parameters */ 3,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[471],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[355],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [57] */
- /* num parameters */ 0,
- /* num template types */ 1,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[299],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [58] */
- /* num parameters */ 1,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[944],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[220],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [59] */
- /* num parameters */ 1,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[945],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[245],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [60] */
- /* num parameters */ 4,
- /* num template types */ 1,
+ /* num parameters */ 6,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[395],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[72],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [61] */
- /* num parameters */ 3,
- /* num template types */ 1,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[561],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[375],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [62] */
- /* num parameters */ 3,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[585],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[150],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [63] */
- /* num parameters */ 3,
- /* num template types */ 1,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[573],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[383],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [64] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[611],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[170],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [65] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[607],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[391],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [66] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[603],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[215],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [67] */
- /* num parameters */ 1,
- /* num template types */ 2,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[953],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[270],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [68] */
- /* num parameters */ 1,
- /* num template types */ 2,
+ /* num parameters */ 6,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[954],
- /* return matcher indices */ &kMatcherIndices[57],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[90],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [69] */
- /* num parameters */ 1,
- /* num template types */ 2,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[6],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[955],
- /* return matcher indices */ &kMatcherIndices[61],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[407],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [70] */
- /* num parameters */ 1,
- /* num template types */ 2,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[956],
- /* return matcher indices */ &kMatcherIndices[65],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[280],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [71] */
- /* num parameters */ 4,
- /* num template types */ 1,
+ /* num parameters */ 3,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[443],
- /* return matcher indices */ &kMatcherIndices[49],
+ /* parameters */ &kParameters[537],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [72] */
- /* num parameters */ 5,
+ /* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[150],
- /* return matcher indices */ &kMatcherIndices[49],
+ /* parameters */ &kParameters[367],
+ /* return matcher indices */ &kMatcherIndices[4],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8522,70 +8877,70 @@
/* num parameters */ 5,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[255],
- /* return matcher indices */ &kMatcherIndices[49],
+ /* parameters */ &kParameters[290],
+ /* return matcher indices */ &kMatcherIndices[4],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [74] */
- /* num parameters */ 6,
+ /* num parameters */ 5,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[90],
- /* return matcher indices */ &kMatcherIndices[49],
+ /* parameters */ &kParameters[265],
+ /* return matcher indices */ &kMatcherIndices[4],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [75] */
- /* num parameters */ 4,
+ /* num parameters */ 6,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[419],
- /* return matcher indices */ &kMatcherIndices[49],
+ /* parameters */ &kParameters[120],
+ /* return matcher indices */ &kMatcherIndices[4],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [76] */
- /* num parameters */ 5,
+ /* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[210],
- /* return matcher indices */ &kMatcherIndices[49],
+ /* parameters */ &kParameters[351],
+ /* return matcher indices */ &kMatcherIndices[4],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [77] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 5,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[567],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[185],
+ /* return matcher indices */ &kMatcherIndices[4],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [78] */
- /* num parameters */ 4,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[411],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[534],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8594,58 +8949,58 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[399],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[343],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [80] */
- /* num parameters */ 5,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[155],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[339],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [81] */
- /* num parameters */ 3,
+ /* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[555],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[190],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [82] */
- /* num parameters */ 4,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[391],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[507],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [83] */
- /* num parameters */ 3,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[477],
- /* return matcher indices */ nullptr,
+ /* parameters */ &kParameters[331],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8654,33 +9009,33 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[480],
+ /* parameters */ &kParameters[540],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [85] */
- /* num parameters */ 4,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[327],
+ /* parameters */ &kParameters[549],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [86] */
- /* num parameters */ 3,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[483],
+ /* parameters */ &kParameters[415],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8690,9 +9045,9 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[489],
+ /* parameters */ &kParameters[552],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8702,33 +9057,33 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[495],
+ /* parameters */ &kParameters[453],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [89] */
- /* num parameters */ 4,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[347],
+ /* parameters */ &kParameters[555],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [90] */
- /* num parameters */ 3,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[501],
+ /* parameters */ &kParameters[419],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8738,9 +9093,9 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[504],
+ /* parameters */ &kParameters[558],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8750,58 +9105,58 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[510],
+ /* parameters */ &kParameters[561],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [93] */
- /* num parameters */ 4,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[367],
+ /* parameters */ &kParameters[564],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [94] */
- /* num parameters */ 3,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[519],
+ /* parameters */ &kParameters[431],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [95] */
- /* num parameters */ 0,
- /* num template types */ 1,
+ /* num parameters */ 3,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[117],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[573],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [96] */
- /* num parameters */ 1,
+ /* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[934],
- /* return matcher indices */ &kMatcherIndices[117],
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[69],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8810,34 +9165,34 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[935],
- /* return matcher indices */ &kMatcherIndices[117],
+ /* parameters */ &kParameters[944],
+ /* return matcher indices */ &kMatcherIndices[69],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [98] */
- /* num parameters */ 3,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[558],
- /* return matcher indices */ &kMatcherIndices[117],
+ /* parameters */ &kParameters[945],
+ /* return matcher indices */ &kMatcherIndices[69],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [99] */
- /* num parameters */ 2,
+ /* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[619],
- /* return matcher indices */ &kMatcherIndices[117],
+ /* parameters */ &kParameters[498],
+ /* return matcher indices */ &kMatcherIndices[69],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8846,23 +9201,23 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[615],
- /* return matcher indices */ &kMatcherIndices[117],
+ /* parameters */ &kParameters[751],
+ /* return matcher indices */ &kMatcherIndices[69],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [101] */
- /* num parameters */ 1,
- /* num template types */ 2,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[939],
- /* return matcher indices */ &kMatcherIndices[123],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[755],
+ /* return matcher indices */ &kMatcherIndices[69],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -8870,10 +9225,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[940],
- /* return matcher indices */ &kMatcherIndices[125],
+ /* parameters */ &kParameters[949],
+ /* return matcher indices */ &kMatcherIndices[39],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8882,10 +9237,10 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[6],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[941],
- /* return matcher indices */ &kMatcherIndices[127],
+ /* parameters */ &kParameters[950],
+ /* return matcher indices */ &kMatcherIndices[65],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8894,35 +9249,35 @@
/* num parameters */ 1,
/* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[6],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[942],
- /* return matcher indices */ &kMatcherIndices[129],
+ /* parameters */ &kParameters[951],
+ /* return matcher indices */ &kMatcherIndices[58],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [105] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[8],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[879],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[952],
+ /* return matcher indices */ &kMatcherIndices[54],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [106] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[878],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[953],
+ /* return matcher indices */ &kMatcherIndices[43],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -8930,10 +9285,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[877],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[808],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8942,10 +9297,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[876],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[807],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8954,10 +9309,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[875],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[806],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -8966,34 +9321,34 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[874],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[805],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [111] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[873],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[804],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [112] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[872],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[803],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9002,10 +9357,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[871],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[802],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9014,382 +9369,382 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[870],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[801],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [115] */
- /* num parameters */ 3,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[531],
- /* return matcher indices */ &kMatcherIndices[49],
+ /* parameters */ &kParameters[800],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [116] */
- /* num parameters */ 3,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[534],
- /* return matcher indices */ &kMatcherIndices[49],
+ /* parameters */ &kParameters[799],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [117] */
- /* num parameters */ 4,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[375],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[759],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [118] */
- /* num parameters */ 3,
+ /* num parameters */ 2,
/* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[588],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[771],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [119] */
- /* num parameters */ 3,
+ /* num parameters */ 2,
/* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[537],
- /* return matcher indices */ &kMatcherIndices[49],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[787],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [120] */
- /* num parameters */ 3,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[540],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[789],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [121] */
- /* num parameters */ 4,
+ /* num parameters */ 2,
/* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[379],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[793],
+ /* return matcher indices */ &kMatcherIndices[11],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [122] */
- /* num parameters */ 3,
+ /* num parameters */ 2,
/* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[543],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[791],
+ /* return matcher indices */ &kMatcherIndices[11],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [123] */
/* num parameters */ 2,
/* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[783],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[1],
+ /* parameters */ &kParameters[591],
+ /* return matcher indices */ &kMatcherIndices[77],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [124] */
/* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[725],
- /* return matcher indices */ &kMatcherIndices[1],
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[1],
+ /* parameters */ &kParameters[595],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [125] */
/* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[723],
- /* return matcher indices */ &kMatcherIndices[37],
+ /* num template types */ 0,
+ /* num template numbers */ 3,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[0],
+ /* parameters */ &kParameters[603],
+ /* return matcher indices */ &kMatcherIndices[23],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [126] */
- /* num parameters */ 2,
+ /* num parameters */ 3,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[721],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[579],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [127] */
- /* num parameters */ 2,
+ /* num parameters */ 3,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[719],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[582],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [128] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[717],
- /* return matcher indices */ &kMatcherIndices[11],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 4,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[435],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [129] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[715],
- /* return matcher indices */ &kMatcherIndices[11],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[585],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [130] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[1],
- /* parameters */ &kParameters[713],
- /* return matcher indices */ &kMatcherIndices[76],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[447],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [131] */
- /* num parameters */ 2,
+ /* num parameters */ 3,
/* num template types */ 0,
- /* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[1],
- /* parameters */ &kParameters[711],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[588],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [132] */
- /* num parameters */ 2,
+ /* num parameters */ 4,
/* num template types */ 0,
- /* num template numbers */ 3,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[0],
- /* parameters */ &kParameters[709],
- /* return matcher indices */ &kMatcherIndices[27],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[359],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [133] */
- /* num parameters */ 4,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[315],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[576],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [134] */
- /* num parameters */ 5,
+ /* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[260],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[601],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [135] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[250],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[104],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [136] */
- /* num parameters */ 6,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[126],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[935],
+ /* return matcher indices */ &kMatcherIndices[104],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [137] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[355],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[936],
+ /* return matcher indices */ &kMatcherIndices[104],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [138] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[15],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[290],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[745],
+ /* return matcher indices */ &kMatcherIndices[104],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [139] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[359],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[938],
+ /* return matcher indices */ &kMatcherIndices[108],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [140] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[275],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[939],
+ /* return matcher indices */ &kMatcherIndices[124],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [141] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[6],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[185],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[940],
+ /* return matcher indices */ &kMatcherIndices[122],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [142] */
- /* num parameters */ 6,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[8],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[138],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[941],
+ /* return matcher indices */ &kMatcherIndices[118],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [143] */
- /* num parameters */ 6,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 2,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[84],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[942],
+ /* return matcher indices */ &kMatcherIndices[110],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [144] */
- /* num parameters */ 7,
+ /* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[65],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[255],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [145] */
- /* num parameters */ 5,
+ /* num parameters */ 6,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[190],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[84],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9398,155 +9753,155 @@
/* num parameters */ 6,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[78],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[108],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [147] */
- /* num parameters */ 5,
+ /* num parameters */ 7,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[230],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[65],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [148] */
- /* num parameters */ 6,
+ /* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[102],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[275],
+ /* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [149] */
- /* num parameters */ 0,
- /* num template types */ 1,
+ /* num parameters */ 6,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[105],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[114],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [150] */
- /* num parameters */ 1,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[926],
- /* return matcher indices */ &kMatcherIndices[105],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[285],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [151] */
- /* num parameters */ 1,
- /* num template types */ 1,
+ /* num parameters */ 6,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[927],
- /* return matcher indices */ &kMatcherIndices[105],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[144],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [152] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[12],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[623],
- /* return matcher indices */ &kMatcherIndices[105],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[363],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [153] */
- /* num parameters */ 1,
- /* num template types */ 2,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[2],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[929],
- /* return matcher indices */ &kMatcherIndices[109],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[165],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [154] */
- /* num parameters */ 1,
- /* num template types */ 2,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[4],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[930],
- /* return matcher indices */ &kMatcherIndices[111],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[160],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [155] */
- /* num parameters */ 1,
- /* num template types */ 2,
+ /* num parameters */ 6,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[6],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[931],
- /* return matcher indices */ &kMatcherIndices[113],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[138],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [156] */
- /* num parameters */ 1,
- /* num template types */ 2,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[932],
- /* return matcher indices */ &kMatcherIndices[115],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[379],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [157] */
- /* num parameters */ 4,
+ /* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[387],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[155],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [158] */
- /* num parameters */ 5,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[175],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[387],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -9554,202 +9909,202 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[180],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[175],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [160] */
- /* num parameters */ 6,
- /* num template types */ 0,
+ /* num parameters */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[144],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[212],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [161] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[371],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[925],
+ /* return matcher indices */ &kMatcherIndices[212],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [162] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[200],
- /* return matcher indices */ &kMatcherIndices[42],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[922],
+ /* return matcher indices */ &kMatcherIndices[212],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [163] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 16,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[431],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[0],
+ /* return matcher indices */ &kMatcherIndices[212],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [164] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 4,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[270],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[411],
+ /* return matcher indices */ &kMatcherIndices[212],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [165] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[215],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[831],
+ /* return matcher indices */ &kMatcherIndices[214],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [166] */
- /* num parameters */ 6,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[120],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[913],
+ /* return matcher indices */ &kMatcherIndices[154],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [167] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[415],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[186],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [168] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[195],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[1011],
+ /* return matcher indices */ &kMatcherIndices[186],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [169] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[407],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1004],
+ /* return matcher indices */ &kMatcherIndices[186],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [170] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 8,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[165],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[57],
+ /* return matcher indices */ &kMatcherIndices[186],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [171] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 4,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[160],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[399],
+ /* return matcher indices */ &kMatcherIndices[186],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [172] */
- /* num parameters */ 6,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[72],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[983],
+ /* return matcher indices */ &kMatcherIndices[190],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [173] */
- /* num parameters */ 4,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[383],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[976],
+ /* return matcher indices */ &kMatcherIndices[188],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [174] */
- /* num parameters */ 5,
- /* num template types */ 0,
+ /* num parameters */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[170],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[160],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [175] */
- /* num parameters */ 0,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[169],
+ /* return matcher indices */ &kMatcherIndices[160],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9758,70 +10113,70 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[9],
+ /* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[962],
- /* return matcher indices */ &kMatcherIndices[169],
+ /* parameters */ &kParameters[985],
+ /* return matcher indices */ &kMatcherIndices[160],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [177] */
- /* num parameters */ 1,
+ /* num parameters */ 8,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[957],
- /* return matcher indices */ &kMatcherIndices[171],
+ /* parameters */ &kParameters[49],
+ /* return matcher indices */ &kMatcherIndices[160],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [178] */
- /* num parameters */ 8,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[49],
- /* return matcher indices */ &kMatcherIndices[171],
+ /* parameters */ &kParameters[785],
+ /* return matcher indices */ &kMatcherIndices[160],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [179] */
- /* num parameters */ 4,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[427],
- /* return matcher indices */ &kMatcherIndices[171],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[988],
+ /* return matcher indices */ &kMatcherIndices[166],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [180] */
- /* num parameters */ 0,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[149],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[989],
+ /* return matcher indices */ &kMatcherIndices[164],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [181] */
- /* num parameters */ 1,
+ /* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[9],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[963],
- /* return matcher indices */ &kMatcherIndices[149],
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[146],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9830,47 +10185,47 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[964],
- /* return matcher indices */ &kMatcherIndices[151],
+ /* parameters */ &kParameters[970],
+ /* return matcher indices */ &kMatcherIndices[146],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [183] */
- /* num parameters */ 6,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[108],
- /* return matcher indices */ &kMatcherIndices[151],
+ /* parameters */ &kParameters[971],
+ /* return matcher indices */ &kMatcherIndices[146],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [184] */
- /* num parameters */ 2,
+ /* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[595],
- /* return matcher indices */ &kMatcherIndices[151],
+ /* parameters */ &kParameters[371],
+ /* return matcher indices */ &kMatcherIndices[146],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [185] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[884],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[777],
+ /* return matcher indices */ &kMatcherIndices[146],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -9878,118 +10233,118 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[883],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[974],
+ /* return matcher indices */ &kMatcherIndices[150],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [187] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[882],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[975],
+ /* return matcher indices */ &kMatcherIndices[148],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [188] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[881],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[174],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [189] */
/* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[3],
- /* parameters */ &kParameters[880],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[998],
+ /* return matcher indices */ &kMatcherIndices[174],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [190] */
- /* num parameters */ 0,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[4],
+ /* parameters */ &kParameters[999],
+ /* return matcher indices */ &kMatcherIndices[174],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [191] */
- /* num parameters */ 1,
+ /* num parameters */ 9,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[9],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[958],
- /* return matcher indices */ &kMatcherIndices[4],
+ /* parameters */ &kParameters[40],
+ /* return matcher indices */ &kMatcherIndices[174],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [192] */
- /* num parameters */ 1,
+ /* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[959],
- /* return matcher indices */ &kMatcherIndices[147],
+ /* parameters */ &kParameters[456],
+ /* return matcher indices */ &kMatcherIndices[174],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [193] */
- /* num parameters */ 4,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[423],
- /* return matcher indices */ &kMatcherIndices[147],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1002],
+ /* return matcher indices */ &kMatcherIndices[178],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [194] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[599],
- /* return matcher indices */ &kMatcherIndices[147],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1003],
+ /* return matcher indices */ &kMatcherIndices[176],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [195] */
/* num parameters */ 0,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[161],
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -9998,10 +10353,10 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[9],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[978],
- /* return matcher indices */ &kMatcherIndices[161],
+ /* parameters */ &kParameters[991],
+ /* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10010,22 +10365,22 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[979],
- /* return matcher indices */ &kMatcherIndices[163],
+ /* parameters */ &kParameters[992],
+ /* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [198] */
- /* num parameters */ 9,
+ /* num parameters */ 6,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[40],
- /* return matcher indices */ &kMatcherIndices[163],
+ /* parameters */ &kParameters[132],
+ /* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10034,23 +10389,23 @@
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[579],
- /* return matcher indices */ &kMatcherIndices[163],
+ /* parameters */ &kParameters[459],
+ /* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [200] */
- /* num parameters */ 0,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[157],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[995],
+ /* return matcher indices */ &kMatcherIndices[172],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -10058,70 +10413,70 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[9],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[973],
- /* return matcher indices */ &kMatcherIndices[157],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[996],
+ /* return matcher indices */ &kMatcherIndices[170],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [202] */
- /* num parameters */ 1,
+ /* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[974],
- /* return matcher indices */ &kMatcherIndices[159],
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[152],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [203] */
- /* num parameters */ 6,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[96],
- /* return matcher indices */ &kMatcherIndices[159],
+ /* parameters */ &kParameters[977],
+ /* return matcher indices */ &kMatcherIndices[152],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [204] */
- /* num parameters */ 3,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[576],
- /* return matcher indices */ &kMatcherIndices[159],
+ /* parameters */ &kParameters[978],
+ /* return matcher indices */ &kMatcherIndices[152],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [205] */
- /* num parameters */ 0,
- /* num template types */ 0,
+ /* num parameters */ 6,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[175],
+ /* parameters */ &kParameters[126],
+ /* return matcher indices */ &kMatcherIndices[152],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [206] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[9],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[925],
- /* return matcher indices */ &kMatcherIndices[175],
+ /* parameters */ &kParameters[783],
+ /* return matcher indices */ &kMatcherIndices[152],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10130,166 +10485,166 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[922],
- /* return matcher indices */ &kMatcherIndices[177],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[981],
+ /* return matcher indices */ &kMatcherIndices[158],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [208] */
- /* num parameters */ 12,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[28],
- /* return matcher indices */ &kMatcherIndices[177],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[982],
+ /* return matcher indices */ &kMatcherIndices[156],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [209] */
- /* num parameters */ 4,
+ /* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[435],
- /* return matcher indices */ &kMatcherIndices[177],
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[196],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [210] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[13],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[737],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[969],
+ /* return matcher indices */ &kMatcherIndices[196],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [211] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[735],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[954],
+ /* return matcher indices */ &kMatcherIndices[196],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [212] */
- /* num parameters */ 2,
+ /* num parameters */ 12,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[731],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[28],
+ /* return matcher indices */ &kMatcherIndices[196],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [213] */
- /* num parameters */ 2,
+ /* num parameters */ 4,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[729],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[403],
+ /* return matcher indices */ &kMatcherIndices[196],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [214] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[727],
- /* return matcher indices */ &kMatcherIndices[11],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[4],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[931],
+ /* return matcher indices */ &kMatcherIndices[210],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [215] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[751],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[928],
+ /* return matcher indices */ &kMatcherIndices[208],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [216] */
- /* num parameters */ 2,
+ /* num parameters */ 0,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[749],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[180],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [217] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[747],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1005],
+ /* return matcher indices */ &kMatcherIndices[180],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [218] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[745],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1006],
+ /* return matcher indices */ &kMatcherIndices[180],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [219] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[743],
- /* return matcher indices */ &kMatcherIndices[11],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 12,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[16],
+ /* return matcher indices */ &kMatcherIndices[180],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [220] */
- /* num parameters */ 0,
- /* num template types */ 0,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[11],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[189],
+ /* parameters */ &kParameters[450],
+ /* return matcher indices */ &kMatcherIndices[180],
/* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10298,11 +10653,11 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[9],
+ /* template types */ &kTemplateTypes[4],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[913],
- /* return matcher indices */ &kMatcherIndices[189],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1009],
+ /* return matcher indices */ &kMatcherIndices[184],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -10310,238 +10665,238 @@
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[2],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[895],
- /* return matcher indices */ &kMatcherIndices[191],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[914],
+ /* return matcher indices */ &kMatcherIndices[182],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [223] */
- /* num parameters */ 16,
- /* num template types */ 1,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[0],
- /* return matcher indices */ &kMatcherIndices[191],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[395],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [224] */
- /* num parameters */ 4,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[351],
- /* return matcher indices */ &kMatcherIndices[191],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[240],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [225] */
- /* num parameters */ 0,
+ /* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[153],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[260],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [226] */
- /* num parameters */ 1,
- /* num template types */ 1,
+ /* num parameters */ 6,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[9],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[968],
- /* return matcher indices */ &kMatcherIndices[153],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[78],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [227] */
- /* num parameters */ 1,
- /* num template types */ 1,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[969],
- /* return matcher indices */ &kMatcherIndices[155],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[443],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [228] */
- /* num parameters */ 8,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[57],
- /* return matcher indices */ &kMatcherIndices[155],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[195],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [229] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[593],
- /* return matcher indices */ &kMatcherIndices[155],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[307],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [230] */
- /* num parameters */ 0,
+ /* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[165],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[230],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [231] */
- /* num parameters */ 1,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[9],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[982],
- /* return matcher indices */ &kMatcherIndices[165],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[235],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [232] */
- /* num parameters */ 1,
- /* num template types */ 1,
+ /* num parameters */ 6,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[977],
- /* return matcher indices */ &kMatcherIndices[167],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[96],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [233] */
- /* num parameters */ 12,
- /* num template types */ 1,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[16],
- /* return matcher indices */ &kMatcherIndices[167],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[303],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [234] */
- /* num parameters */ 3,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[10],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[582],
- /* return matcher indices */ &kMatcherIndices[167],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[250],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [235] */
- /* num parameters */ 2,
+ /* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[689],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[327],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [236] */
- /* num parameters */ 2,
+ /* num parameters */ 5,
/* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[687],
- /* return matcher indices */ &kMatcherIndices[44],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[200],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [237] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 5,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[685],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[205],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [238] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[683],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[102],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [239] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 4,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[699],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[311],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [240] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[697],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[225],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [241] */
/* num parameters */ 2,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[695],
- /* return matcher indices */ &kMatcherIndices[37],
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[741],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10550,10 +10905,10 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[693],
- /* return matcher indices */ &kMatcherIndices[37],
+ /* parameters */ &kParameters[747],
+ /* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10561,11 +10916,11 @@
/* [243] */
/* num parameters */ 2,
/* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[707],
- /* return matcher indices */ &kMatcherIndices[1],
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[749],
+ /* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -10574,347 +10929,347 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[705],
- /* return matcher indices */ &kMatcherIndices[37],
+ /* parameters */ &kParameters[753],
+ /* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [245] */
/* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[703],
- /* return matcher indices */ &kMatcherIndices[37],
+ /* parameters */ &kParameters[757],
+ /* return matcher indices */ &kMatcherIndices[11],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [246] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[701],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[813],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [247] */
- /* num parameters */ 2,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[681],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[812],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [248] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[679],
- /* return matcher indices */ &kMatcherIndices[44],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[811],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [249] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[677],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[810],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [250] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[675],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[3],
+ /* parameters */ &kParameters[809],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [251] */
- /* num parameters */ 3,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[522],
+ /* parameters */ &kParameters[663],
/* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [252] */
- /* num parameters */ 3,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[525],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[679],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [253] */
- /* num parameters */ 3,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[528],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[683],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [254] */
- /* num parameters */ 0,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[689],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [255] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[914],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[739],
+ /* return matcher indices */ &kMatcherIndices[11],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [256] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[18],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[915],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[681],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [257] */
- /* num parameters */ 0,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[649],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [258] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[917],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[653],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [259] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[17],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[918],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[657],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [260] */
- /* num parameters */ 0,
+ /* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[667],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [261] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[920],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[669],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [262] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[16],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[921],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[671],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [263] */
- /* num parameters */ 0,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[673],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [264] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[923],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[675],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [265] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[15],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[924],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[677],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [266] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[459],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[691],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [267] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[462],
+ /* parameters */ &kParameters[693],
/* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [268] */
- /* num parameters */ 3,
- /* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[465],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[611],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [269] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[852],
- /* return matcher indices */ &kMatcherIndices[21],
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[623],
+ /* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [270] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[853],
- /* return matcher indices */ &kMatcherIndices[44],
+ /* parameters */ &kParameters[639],
+ /* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [271] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[810],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[641],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [272] */
- /* num parameters */ 1,
+ /* num parameters */ 0,
/* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[824],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -10922,263 +11277,263 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[827],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[920],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [274] */
/* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[828],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[921],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [275] */
- /* num parameters */ 4,
- /* num template types */ 1,
+ /* num parameters */ 0,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[439],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [276] */
- /* num parameters */ 4,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[403],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[932],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [277] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[19],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[832],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[933],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [278] */
- /* num parameters */ 1,
+ /* num parameters */ 0,
/* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[840],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[66],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [279] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[781],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[929],
+ /* return matcher indices */ &kMatcherIndices[66],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [280] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[779],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[18],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[930],
+ /* return matcher indices */ &kMatcherIndices[66],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [281] */
- /* num parameters */ 1,
+ /* num parameters */ 0,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[842],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [282] */
/* num parameters */ 1,
/* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[843],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[926],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [283] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[20],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[844],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[927],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [284] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[845],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[18],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[510],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [285] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[846],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[18],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[543],
+ /* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [286] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[847],
+ /* parameters */ &kParameters[546],
/* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [287] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 0,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[765],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1013],
+ /* return matcher indices */ &kMatcherIndices[55],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [288] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[763],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[923],
+ /* return matcher indices */ &kMatcherIndices[55],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [289] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[21],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[761],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[924],
+ /* return matcher indices */ &kMatcherIndices[55],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [290] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[759],
- /* return matcher indices */ &kMatcherIndices[37],
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[477],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [291] */
- /* num parameters */ 1,
+ /* num parameters */ 3,
/* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[799],
- /* return matcher indices */ &kMatcherIndices[202],
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[480],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [292] */
- /* num parameters */ 1,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[798],
- /* return matcher indices */ &kMatcherIndices[145],
+ /* parameters */ &kParameters[483],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [293] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[848],
- /* return matcher indices */ &kMatcherIndices[201],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[860],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [294] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[849],
- /* return matcher indices */ &kMatcherIndices[119],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[861],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -11186,10 +11541,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[801],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[890],
+ /* return matcher indices */ &kMatcherIndices[225],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11198,10 +11553,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[800],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[889],
+ /* return matcher indices */ &kMatcherIndices[162],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11210,10 +11565,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[825],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[888],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
@@ -11222,106 +11577,106 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[826],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[887],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [299] */
- /* num parameters */ 3,
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[450],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[892],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [300] */
- /* num parameters */ 3,
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[447],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[891],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [301] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[805],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[884],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [302] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[804],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[883],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [303] */
- /* num parameters */ 1,
+ /* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[807],
+ /* parameters */ &kParameters[423],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [304] */
- /* num parameters */ 1,
+ /* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[806],
- /* return matcher indices */ &kMatcherIndices[37],
+ /* parameters */ &kParameters[427],
+ /* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [305] */
- /* num parameters */ 3,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[468],
- /* return matcher indices */ &kMatcherIndices[1],
+ /* parameters */ &kParameters[882],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [306] */
- /* num parameters */ 3,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[456],
- /* return matcher indices */ &kMatcherIndices[37],
+ /* parameters */ &kParameters[881],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11330,10 +11685,10 @@
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[741],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[593],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11342,10 +11697,10 @@
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[739],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[631],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11354,10 +11709,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[863],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[880],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11366,10 +11721,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[864],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[879],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11378,10 +11733,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[809],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[878],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11390,10 +11745,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[808],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[877],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11402,10 +11757,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[811],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[876],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11414,83 +11769,83 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[886],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[875],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [315] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[865],
+ /* parameters */ &kParameters[769],
/* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [316] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[866],
- /* return matcher indices */ &kMatcherIndices[37],
+ /* parameters */ &kParameters[765],
+ /* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [317] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[867],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[763],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [318] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[885],
+ /* parameters */ &kParameters[761],
/* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [319] */
- /* num parameters */ 1,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[813],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[522],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [320] */
- /* num parameters */ 1,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[812],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[528],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -11498,10 +11853,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[887],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[874],
+ /* return matcher indices */ &kMatcherIndices[224],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11510,10 +11865,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[888],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[873],
+ /* return matcher indices */ &kMatcherIndices[114],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11522,10 +11877,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[889],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[894],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11534,10 +11889,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[890],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[893],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11546,11 +11901,11 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[891],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[886],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -11558,82 +11913,82 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[892],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[885],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [327] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[549],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[898],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [328] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[552],
+ /* parameters */ &kParameters[897],
/* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [329] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[893],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[513],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [330] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[894],
+ /* parameters */ &kParameters[516],
/* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [331] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[673],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[899],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [332] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[671],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[1012],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11642,11 +11997,11 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[815],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[901],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -11654,34 +12009,34 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[814],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[900],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [335] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[896],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[687],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [336] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[897],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[685],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11690,10 +12045,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[898],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[866],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -11702,35 +12057,35 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[899],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[865],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [339] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[629],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[903],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [340] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[627],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[902],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -11738,11 +12093,11 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[901],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[905],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -11750,179 +12105,179 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[903],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[904],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [343] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[817],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[864],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [344] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[816],
+ /* parameters */ &kParameters[857],
/* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [345] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[645],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[856],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [346] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[641],
- /* return matcher indices */ &kMatcherIndices[44],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[855],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [347] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[649],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[907],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [348] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[647],
- /* return matcher indices */ &kMatcherIndices[44],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[906],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [349] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[653],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[853],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [350] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[651],
- /* return matcher indices */ &kMatcherIndices[44],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[852],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [351] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[657],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[851],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [352] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[655],
- /* return matcher indices */ &kMatcherIndices[44],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[850],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [353] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[661],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[849],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [354] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[659],
- /* return matcher indices */ &kMatcherIndices[44],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[848],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [355] */
- /* num parameters */ 1,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[819],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[567],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [356] */
- /* num parameters */ 1,
+ /* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[818],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[570],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -11930,11 +12285,11 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[821],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[846],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -11942,94 +12297,94 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[820],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[845],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [359] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[823],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[599],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [360] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[822],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* parameters */ &kParameters[597],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [361] */
- /* num parameters */ 2,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[787],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[896],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [362] */
- /* num parameters */ 2,
- /* num template types */ 0,
+ /* num parameters */ 1,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[789],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[895],
+ /* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [363] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[983],
- /* return matcher indices */ &kMatcherIndices[1],
+ /* parameters */ &kParameters[843],
+ /* return matcher indices */ &kMatcherIndices[14],
/* 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 */ 1,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[960],
- /* return matcher indices */ &kMatcherIndices[37],
+ /* parameters */ &kParameters[842],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [365] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[869],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* parameters */ &kParameters[841],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -12037,11 +12392,11 @@
/* [366] */
/* num parameters */ 1,
/* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[868],
- /* return matcher indices */ &kMatcherIndices[41],
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[840],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -12050,11 +12405,11 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[831],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[909],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
@@ -12062,273 +12417,273 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[830],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[908],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [369] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[665],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[838],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [370] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[13],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[663],
- /* return matcher indices */ &kMatcherIndices[44],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[837],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [371] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[834],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[911],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [372] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[833],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[910],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [373] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[837],
+ /* parameters */ &kParameters[735],
/* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [374] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[836],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[743],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [375] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[839],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[1010],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [376] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[838],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[912],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
/* const eval */ nullptr,
},
{
/* [377] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[936],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[795],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [378] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[851],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[719],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [379] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[947],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[715],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [380] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[946],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[717],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [381] */
- /* num parameters */ 3,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[570],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[711],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [382] */
- /* num parameters */ 3,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[564],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[713],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [383] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[949],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[729],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [384] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[948],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[727],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [385] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[597],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[917],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [386] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[601],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[916],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [387] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[691],
+ /* parameters */ &kParameters[854],
/* 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,
},
{
/* [388] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[757],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[844],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [389] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[975],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[937],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [390] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[970],
+ /* parameters */ &kParameters[918],
/* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12336,23 +12691,23 @@
{
/* [391] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[980],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[947],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [392] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[976],
+ /* parameters */ &kParameters[946],
/* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -12360,12 +12715,12 @@
{
/* [393] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[967],
- /* return matcher indices */ &kMatcherIndices[21],
+ /* parameters */ &kParameters[798],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -12373,156 +12728,156 @@
/* [394] */
/* num parameters */ 1,
/* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[972],
- /* return matcher indices */ &kMatcherIndices[21],
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[797],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [395] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[933],
- /* return matcher indices */ &kMatcherIndices[21],
+ /* parameters */ &kParameters[957],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [396] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[943],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [397] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[916],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [398] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[919],
+ /* parameters */ &kParameters[948],
/* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [399] */
- /* num parameters */ 1,
+ /* [397] */
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[19],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[856],
- /* return matcher indices */ &kMatcherIndices[1],
+ /* parameters */ &kParameters[707],
+ /* return matcher indices */ &kMatcherIndices[17],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
+ /* [398] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[709],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [399] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[959],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
/* [400] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[19],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[857],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[958],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [401] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[854],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[961],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [402] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[855],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[960],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [403] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[803],
- /* return matcher indices */ &kMatcherIndices[5],
+ /* parameters */ &kParameters[462],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [404] */
- /* num parameters */ 1,
- /* num template types */ 0,
+ /* num parameters */ 3,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[802],
+ /* parameters */ &kParameters[465],
/* return matcher indices */ &kMatcherIndices[31],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [405] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[637],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[963],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [406] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[633],
- /* return matcher indices */ &kMatcherIndices[37],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[962],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -12530,59 +12885,59 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[971],
- /* return matcher indices */ &kMatcherIndices[109],
+ /* parameters */ &kParameters[973],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [408] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[755],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[972],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [409] */
/* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[591],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[781],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [410] */
/* num parameters */ 2,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[767],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[779],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [411] */
/* num parameters */ 2,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[769],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[16],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[703],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -12590,23 +12945,23 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[771],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* template types */ &kTemplateTypes[16],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[705],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [413] */
/* num parameters */ 2,
/* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[773],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[16],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[699],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -12614,83 +12969,83 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[775],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* template types */ &kTemplateTypes[16],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[701],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [415] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[777],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[980],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [416] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[841],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [417] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[669],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [418] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[667],
- /* return matcher indices */ &kMatcherIndices[21],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [419] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[860],
- /* return matcher indices */ &kMatcherIndices[62],
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[979],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [420] */
- /* num parameters */ 0,
+ /* [417] */
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[987],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [418] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[986],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [419] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[659],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [420] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[661],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -12698,10 +13053,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[961],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* parameters */ &kParameters[994],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -12709,11 +13064,11 @@
/* [422] */
/* num parameters */ 1,
/* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[965],
- /* return matcher indices */ &kMatcherIndices[42],
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[993],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -12722,23 +13077,23 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[966],
- /* return matcher indices */ &kMatcherIndices[109],
+ /* parameters */ &kParameters[1007],
+ /* return matcher indices */ &kMatcherIndices[17],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [424] */
- /* num parameters */ 2,
- /* num template types */ 1,
+ /* num parameters */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
- /* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[753],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[1001],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -12746,10 +13101,10 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[797],
- /* return matcher indices */ &kMatcherIndices[109],
+ /* parameters */ &kParameters[997],
+ /* return matcher indices */ &kMatcherIndices[17],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -12757,47 +13112,47 @@
/* [426] */
/* num parameters */ 1,
/* num template types */ 0,
- /* num template numbers */ 2,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[5],
- /* parameters */ &kParameters[900],
- /* return matcher indices */ &kMatcherIndices[23],
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[1008],
+ /* return matcher indices */ &kMatcherIndices[17],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [427] */
- /* num parameters */ 0,
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
- /* return matcher indices */ nullptr,
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[943],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [428] */
- /* num parameters */ 3,
+ /* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[507],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [429] */
- /* num parameters */ 2,
+ /* num parameters */ 1,
/* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[733],
- /* return matcher indices */ &kMatcherIndices[31],
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[919],
+ /* return matcher indices */ &kMatcherIndices[14],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
@@ -12805,36 +13160,36 @@
/* [430] */
/* num parameters */ 1,
/* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[862],
- /* return matcher indices */ &kMatcherIndices[62],
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[934],
+ /* return matcher indices */ &kMatcherIndices[34],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [431] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[861],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[862],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [432] */
/* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[859],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[863],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -12842,11 +13197,11 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[858],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -12854,59 +13209,59 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[850],
- /* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* parameters */ &kParameters[859],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [435] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[829],
- /* return matcher indices */ &kMatcherIndices[5],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[731],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [436] */
- /* num parameters */ 3,
- /* num template types */ 0,
+ /* num parameters */ 2,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[20],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[453],
+ /* parameters */ &kParameters[733],
/* return matcher indices */ &kMatcherIndices[31],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [437] */
- /* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[795],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[531],
+ /* return matcher indices */ &kMatcherIndices[200],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [438] */
/* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[793],
- /* return matcher indices */ &kMatcherIndices[41],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[645],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
@@ -12914,49 +13269,409 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[8],
- /* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[791],
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[635],
/* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [440] */
/* num parameters */ 2,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[20],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[785],
- /* return matcher indices */ &kMatcherIndices[123],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[615],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [441] */
- /* num parameters */ 1,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[14],
- /* template numbers */ &kTemplateNumbers[8],
- /* parameters */ &kParameters[981],
- /* return matcher indices */ &kMatcherIndices[62],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[627],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
/* [442] */
- /* num parameters */ 3,
+ /* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[11],
+ /* template types */ &kTemplateTypes[10],
/* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[546],
- /* return matcher indices */ &kMatcherIndices[173],
+ /* parameters */ &kParameters[619],
+ /* 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[10],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[613],
+ /* 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[10],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[609],
+ /* 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[10],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[607],
+ /* 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[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[695],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* 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[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[697],
+ /* return matcher indices */ &kMatcherIndices[17],
+ /* 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[10],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[605],
+ /* 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[10],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[847],
+ /* 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[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1013],
+ /* 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[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1013],
+ /* 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[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[832],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* 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[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[833],
+ /* return matcher indices */ &kMatcherIndices[106],
+ /* 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,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[834],
+ /* return matcher indices */ &kMatcherIndices[108],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [455] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[835],
+ /* return matcher indices */ &kMatcherIndices[108],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [456] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[836],
+ /* return matcher indices */ &kMatcherIndices[108],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [457] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[5],
+ /* parameters */ &kParameters[839],
+ /* return matcher indices */ &kMatcherIndices[19],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [458] */
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[525],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [459] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[665],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [460] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[867],
+ /* return matcher indices */ &kMatcherIndices[55],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [461] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[868],
+ /* return matcher indices */ &kMatcherIndices[55],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [462] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[869],
+ /* return matcher indices */ &kMatcherIndices[55],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [463] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[870],
+ /* return matcher indices */ &kMatcherIndices[55],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [464] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[872],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [465] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[737],
+ /* return matcher indices */ &kMatcherIndices[39],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [466] */
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[519],
+ /* return matcher indices */ &kMatcherIndices[34],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [467] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[721],
+ /* return matcher indices */ &kMatcherIndices[55],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [468] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[723],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [469] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[14],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[725],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [470] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[24],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[915],
+ /* return matcher indices */ &kMatcherIndices[14],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [471] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[17],
+ /* template numbers */ &kTemplateNumbers[8],
+ /* parameters */ &kParameters[1000],
+ /* return matcher indices */ &kMatcherIndices[55],
+ /* 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[24],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[871],
+ /* return matcher indices */ &kMatcherIndices[55],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ nullptr,
+ },
};
constexpr IntrinsicInfo kBuiltins[] = {
@@ -12965,549 +13680,570 @@
/* fn abs<T : fiu32>(T) -> T */
/* fn abs<N : num, T : fiu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[363],
+ /* overloads */ &kOverloads[387],
},
{
/* [1] */
/* fn acos(f32) -> f32 */
/* fn acos<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[397],
+ /* overloads */ &kOverloads[429],
},
{
/* [2] */
- /* fn all(bool) -> bool */
- /* fn all<N : num>(vec<N, bool>) -> bool */
+ /* fn acosh(f32) -> f32 */
+ /* fn acosh<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[395],
+ /* overloads */ &kOverloads[427],
},
{
/* [3] */
- /* fn any(bool) -> bool */
- /* fn any<N : num>(vec<N, bool>) -> bool */
+ /* fn all(bool) -> bool */
+ /* fn all<N : num>(vec<N, bool>) -> bool */
/* num overloads */ 2,
- /* overloads */ &kOverloads[393],
+ /* overloads */ &kOverloads[425],
},
{
/* [4] */
- /* fn arrayLength<T, A : access>(ptr<storage, array<T>, A>) -> u32 */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[441],
+ /* fn any(bool) -> bool */
+ /* fn any<N : num>(vec<N, bool>) -> bool */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[423],
},
{
/* [5] */
- /* fn asin(f32) -> f32 */
- /* fn asin<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[391],
+ /* fn arrayLength<T, A : access>(ptr<storage, array<T>, A>) -> u32 */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[471],
},
{
/* [6] */
- /* fn atan(f32) -> f32 */
- /* fn atan<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* fn asin(f32) -> f32 */
+ /* fn asin<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[389],
+ /* overloads */ &kOverloads[421],
},
{
/* [7] */
- /* fn atan2(f32, f32) -> f32 */
- /* fn atan2<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+ /* fn asinh(f32) -> f32 */
+ /* fn asinh<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[385],
+ /* overloads */ &kOverloads[417],
},
{
/* [8] */
- /* fn ceil(f32) -> f32 */
- /* fn ceil<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* fn atan(f32) -> f32 */
+ /* fn atan<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[383],
+ /* overloads */ &kOverloads[415],
},
{
/* [9] */
- /* fn clamp<T : fiu32>(T, T, T) -> T */
- /* fn clamp<N : num, T : fiu32>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
+ /* fn atan2(f32, f32) -> f32 */
+ /* fn atan2<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[381],
+ /* overloads */ &kOverloads[409],
},
{
/* [10] */
- /* fn cos(f32) -> f32 */
- /* fn cos<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* fn atanh(f32) -> f32 */
+ /* fn atanh<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[379],
+ /* overloads */ &kOverloads[407],
},
{
/* [11] */
- /* fn cosh(f32) -> f32 */
- /* fn cosh<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* fn ceil(f32) -> f32 */
+ /* fn ceil<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[377],
+ /* overloads */ &kOverloads[405],
},
{
/* [12] */
- /* fn countLeadingZeros<T : iu32>(T) -> T */
- /* fn countLeadingZeros<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[375],
- },
- {
- /* [13] */
- /* fn countOneBits<T : iu32>(T) -> T */
- /* fn countOneBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[373],
- },
- {
- /* [14] */
- /* fn countTrailingZeros<T : iu32>(T) -> T */
- /* fn countTrailingZeros<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[371],
- },
- {
- /* [15] */
- /* fn cross(vec3<f32>, vec3<f32>) -> vec3<f32> */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[440],
- },
- {
- /* [16] */
- /* fn degrees(f32) -> f32 */
- /* fn degrees<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[367],
- },
- {
- /* [17] */
- /* fn determinant<N : num>(mat<N, N, f32>) -> f32 */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[435],
- },
- {
- /* [18] */
- /* fn distance(f32, f32) -> f32 */
- /* fn distance<N : num>(vec<N, f32>, vec<N, f32>) -> f32 */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[361],
- },
- {
- /* [19] */
- /* fn dot<N : num, T : fiu32>(vec<N, T>, vec<N, T>) -> T */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[439],
- },
- {
- /* [20] */
- /* fn dot4I8Packed(u32, u32) -> i32 */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[438],
- },
- {
- /* [21] */
- /* fn dot4U8Packed(u32, u32) -> u32 */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[437],
- },
- {
- /* [22] */
- /* fn dpdx(f32) -> f32 */
- /* fn dpdx<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[359],
- },
- {
- /* [23] */
- /* fn dpdxCoarse(f32) -> f32 */
- /* fn dpdxCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[357],
- },
- {
- /* [24] */
- /* fn dpdxFine(f32) -> f32 */
- /* fn dpdxFine<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[355],
- },
- {
- /* [25] */
- /* fn dpdy(f32) -> f32 */
- /* fn dpdy<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[343],
- },
- {
- /* [26] */
- /* fn dpdyCoarse(f32) -> f32 */
- /* fn dpdyCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[333],
- },
- {
- /* [27] */
- /* fn dpdyFine(f32) -> f32 */
- /* fn dpdyFine<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[319],
- },
- {
- /* [28] */
- /* fn exp(f32) -> f32 */
- /* fn exp<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[313],
- },
- {
- /* [29] */
- /* fn exp2(f32) -> f32 */
- /* fn exp2<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[311],
- },
- {
- /* [30] */
- /* fn extractBits<T : iu32>(T, u32, u32) -> T */
- /* fn extractBits<N : num, T : iu32>(vec<N, T>, u32, u32) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[305],
- },
- {
- /* [31] */
- /* fn faceForward<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[436],
- },
- {
- /* [32] */
- /* fn firstLeadingBit<T : iu32>(T) -> T */
- /* fn firstLeadingBit<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[303],
- },
- {
- /* [33] */
- /* fn firstTrailingBit<T : iu32>(T) -> T */
- /* fn firstTrailingBit<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[301],
- },
- {
- /* [34] */
- /* fn floor(f32) -> f32 */
- /* fn floor<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* fn clamp<T : fiu32>(T, T, T) -> T */
+ /* fn clamp<N : num, T : fiu32>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
/* overloads */ &kOverloads[403],
},
{
- /* [35] */
- /* fn fma(f32, f32, f32) -> f32 */
- /* fn fma<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+ /* [13] */
+ /* fn cos(f32) -> f32 */
+ /* fn cos<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[299],
+ /* overloads */ &kOverloads[401],
},
{
- /* [36] */
- /* fn fract(f32) -> f32 */
- /* fn fract<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* [14] */
+ /* fn cosh(f32) -> f32 */
+ /* fn cosh<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[295],
+ /* overloads */ &kOverloads[399],
},
{
- /* [37] */
- /* fn frexp(f32) -> __frexp_result */
- /* fn frexp<N : num>(vec<N, f32>) -> __frexp_result_vec<N> */
+ /* [15] */
+ /* fn countLeadingZeros<T : iu32>(T) -> T */
+ /* fn countLeadingZeros<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[291],
+ /* overloads */ &kOverloads[395],
},
{
- /* [38] */
- /* fn fwidth(f32) -> f32 */
- /* fn fwidth<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* [16] */
+ /* fn countOneBits<T : iu32>(T) -> T */
+ /* fn countOneBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[271],
+ /* overloads */ &kOverloads[391],
},
{
- /* [39] */
- /* fn fwidthCoarse(f32) -> f32 */
- /* fn fwidthCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* [17] */
+ /* fn countTrailingZeros<T : iu32>(T) -> T */
+ /* fn countTrailingZeros<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[297],
+ /* overloads */ &kOverloads[389],
},
{
- /* [40] */
- /* fn fwidthFine(f32) -> f32 */
- /* fn fwidthFine<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[273],
- },
- {
- /* [41] */
- /* 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> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[275],
- },
- {
- /* [42] */
- /* fn inverseSqrt(f32) -> f32 */
- /* fn inverseSqrt<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[277],
- },
- {
- /* [43] */
- /* fn ldexp(f32, i32) -> f32 */
- /* fn ldexp<N : num>(vec<N, f32>, vec<N, i32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[279],
- },
- {
- /* [44] */
- /* fn length(f32) -> f32 */
- /* fn length<N : num>(vec<N, f32>) -> f32 */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[281],
- },
- {
- /* [45] */
- /* fn log(f32) -> f32 */
- /* fn log<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[283],
- },
- {
- /* [46] */
- /* fn log2(f32) -> f32 */
- /* fn log2<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[285],
- },
- {
- /* [47] */
- /* fn max<T : fiu32>(T, T) -> T */
- /* fn max<N : num, T : fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[287],
- },
- {
- /* [48] */
- /* fn min<T : fiu32>(T, T) -> T */
- /* fn min<N : num, T : fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[289],
- },
- {
- /* [49] */
- /* fn mix(f32, f32, f32) -> f32 */
- /* fn mix<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
- /* fn mix<N : num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32> */
- /* num overloads */ 3,
- /* overloads */ &kOverloads[266],
- },
- {
- /* [50] */
- /* fn modf(f32) -> __modf_result */
- /* fn modf<N : num>(vec<N, f32>) -> __modf_result_vec<N> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[293],
- },
- {
- /* [51] */
- /* fn normalize<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* [18] */
+ /* fn cross(vec3<f32>, vec3<f32>) -> vec3<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[434],
+ /* overloads */ &kOverloads[465],
},
{
- /* [52] */
- /* fn pack2x16float(vec2<f32>) -> u32 */
+ /* [19] */
+ /* fn degrees(f32) -> f32 */
+ /* fn degrees<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[385],
+ },
+ {
+ /* [20] */
+ /* fn determinant<N : num>(mat<N, N, f32>) -> f32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[433],
+ /* overloads */ &kOverloads[470],
},
{
- /* [53] */
- /* fn pack2x16snorm(vec2<f32>) -> u32 */
+ /* [21] */
+ /* fn distance(f32, f32) -> f32 */
+ /* fn distance<N : num>(vec<N, f32>, vec<N, f32>) -> f32 */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[383],
+ },
+ {
+ /* [22] */
+ /* fn dot<N : num, T : fiu32>(vec<N, T>, vec<N, T>) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[432],
+ /* overloads */ &kOverloads[469],
},
{
- /* [54] */
- /* fn pack2x16unorm(vec2<f32>) -> u32 */
+ /* [23] */
+ /* fn dot4I8Packed(u32, u32) -> i32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[419],
+ /* overloads */ &kOverloads[468],
},
{
- /* [55] */
- /* fn pack4x8snorm(vec4<f32>) -> u32 */
+ /* [24] */
+ /* fn dot4U8Packed(u32, u32) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[431],
+ /* overloads */ &kOverloads[467],
},
{
- /* [56] */
- /* fn pack4x8unorm(vec4<f32>) -> u32 */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[430],
- },
- {
- /* [57] */
- /* fn pow(f32, f32) -> f32 */
- /* fn pow<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+ /* [25] */
+ /* fn dpdx(f32) -> f32 */
+ /* fn dpdx<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[307],
+ /* overloads */ &kOverloads[375],
},
{
- /* [58] */
- /* fn radians(f32) -> f32 */
- /* fn radians<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* [26] */
+ /* fn dpdxCoarse(f32) -> f32 */
+ /* fn dpdxCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[309],
+ /* overloads */ &kOverloads[371],
},
{
- /* [59] */
- /* fn reflect<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[429],
- },
- {
- /* [60] */
- /* fn refract<N : num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32> */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[428],
- },
- {
- /* [61] */
- /* fn reverseBits<T : iu32>(T) -> T */
- /* fn reverseBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
+ /* [27] */
+ /* fn dpdxFine(f32) -> f32 */
+ /* fn dpdxFine<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[315],
+ /* overloads */ &kOverloads[367],
},
{
- /* [62] */
- /* fn round(f32) -> f32 */
- /* fn round<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* [28] */
+ /* fn dpdy(f32) -> f32 */
+ /* fn dpdy<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[317],
+ /* overloads */ &kOverloads[347],
},
{
- /* [63] */
- /* 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> */
- /* num overloads */ 3,
- /* overloads */ &kOverloads[251],
- },
- {
- /* [64] */
- /* fn sign(f32) -> f32 */
- /* fn sign<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[321],
- },
- {
- /* [65] */
- /* fn sin(f32) -> f32 */
- /* fn sin<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[323],
- },
- {
- /* [66] */
- /* fn sinh(f32) -> f32 */
- /* fn sinh<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[325],
- },
- {
- /* [67] */
- /* fn smoothstep(f32, f32, f32) -> f32 */
- /* fn smoothstep<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[327],
- },
- {
- /* [68] */
- /* fn sqrt(f32) -> f32 */
- /* fn sqrt<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[329],
- },
- {
- /* [69] */
- /* fn step(f32, f32) -> f32 */
- /* fn step<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[331],
- },
- {
- /* [70] */
- /* fn storageBarrier() */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[427],
- },
- {
- /* [71] */
- /* fn tan(f32) -> f32 */
- /* fn tan<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[335],
- },
- {
- /* [72] */
- /* fn tanh(f32) -> f32 */
- /* fn tanh<N : num>(vec<N, f32>) -> vec<N, f32> */
- /* num overloads */ 2,
- /* overloads */ &kOverloads[337],
- },
- {
- /* [73] */
- /* fn transpose<M : num, N : num>(mat<M, N, f32>) -> mat<N, M, f32> */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[426],
- },
- {
- /* [74] */
- /* fn trunc(f32) -> f32 */
- /* fn trunc<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* [29] */
+ /* fn dpdyCoarse(f32) -> f32 */
+ /* fn dpdyCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
/* overloads */ &kOverloads[341],
},
{
- /* [75] */
- /* fn unpack2x16float(u32) -> vec2<f32> */
+ /* [30] */
+ /* fn dpdyFine(f32) -> f32 */
+ /* fn dpdyFine<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[339],
+ },
+ {
+ /* [31] */
+ /* fn exp(f32) -> f32 */
+ /* fn exp<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[333],
+ },
+ {
+ /* [32] */
+ /* fn exp2(f32) -> f32 */
+ /* fn exp2<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[331],
+ },
+ {
+ /* [33] */
+ /* fn extractBits<T : iu32>(T, u32, u32) -> T */
+ /* fn extractBits<N : num, T : iu32>(vec<N, T>, u32, u32) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[329],
+ },
+ {
+ /* [34] */
+ /* fn faceForward<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[425],
+ /* overloads */ &kOverloads[466],
+ },
+ {
+ /* [35] */
+ /* fn firstLeadingBit<T : iu32>(T) -> T */
+ /* fn firstLeadingBit<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[327],
+ },
+ {
+ /* [36] */
+ /* fn firstTrailingBit<T : iu32>(T) -> T */
+ /* fn firstTrailingBit<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[361],
+ },
+ {
+ /* [37] */
+ /* fn floor(f32) -> f32 */
+ /* fn floor<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[323],
+ },
+ {
+ /* [38] */
+ /* fn fma(f32, f32, f32) -> f32 */
+ /* fn fma<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[319],
+ },
+ {
+ /* [39] */
+ /* fn fract(f32) -> f32 */
+ /* fn fract<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[299],
+ },
+ {
+ /* [40] */
+ /* fn frexp(f32) -> __frexp_result */
+ /* fn frexp<N : num>(vec<N, f32>) -> __frexp_result_vec<N> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[295],
+ },
+ {
+ /* [41] */
+ /* fn fwidth(f32) -> f32 */
+ /* fn fwidth<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[297],
+ },
+ {
+ /* [42] */
+ /* fn fwidthCoarse(f32) -> f32 */
+ /* fn fwidthCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[325],
+ },
+ {
+ /* [43] */
+ /* fn fwidthFine(f32) -> f32 */
+ /* fn fwidthFine<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[301],
+ },
+ {
+ /* [44] */
+ /* 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> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[303],
+ },
+ {
+ /* [45] */
+ /* fn inverseSqrt(f32) -> f32 */
+ /* fn inverseSqrt<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[305],
+ },
+ {
+ /* [46] */
+ /* fn ldexp(f32, i32) -> f32 */
+ /* fn ldexp<N : num>(vec<N, f32>, vec<N, i32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[307],
+ },
+ {
+ /* [47] */
+ /* fn length(f32) -> f32 */
+ /* fn length<N : num>(vec<N, f32>) -> f32 */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[309],
+ },
+ {
+ /* [48] */
+ /* fn log(f32) -> f32 */
+ /* fn log<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[311],
+ },
+ {
+ /* [49] */
+ /* fn log2(f32) -> f32 */
+ /* fn log2<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[313],
+ },
+ {
+ /* [50] */
+ /* fn max<T : fiu32>(T, T) -> T */
+ /* fn max<N : num, T : fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[315],
+ },
+ {
+ /* [51] */
+ /* fn min<T : fiu32>(T, T) -> T */
+ /* fn min<N : num, T : fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[317],
+ },
+ {
+ /* [52] */
+ /* fn mix(f32, f32, f32) -> f32 */
+ /* fn mix<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+ /* fn mix<N : num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32> */
+ /* num overloads */ 3,
+ /* overloads */ &kOverloads[290],
+ },
+ {
+ /* [53] */
+ /* fn modf(f32) -> __modf_result */
+ /* fn modf<N : num>(vec<N, f32>) -> __modf_result_vec<N> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[321],
+ },
+ {
+ /* [54] */
+ /* fn normalize<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[464],
+ },
+ {
+ /* [55] */
+ /* fn pack2x16float(vec2<f32>) -> u32 */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[472],
+ },
+ {
+ /* [56] */
+ /* fn pack2x16snorm(vec2<f32>) -> u32 */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[463],
+ },
+ {
+ /* [57] */
+ /* fn pack2x16unorm(vec2<f32>) -> u32 */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[462],
+ },
+ {
+ /* [58] */
+ /* fn pack4x8snorm(vec4<f32>) -> u32 */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[461],
+ },
+ {
+ /* [59] */
+ /* fn pack4x8unorm(vec4<f32>) -> u32 */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[460],
+ },
+ {
+ /* [60] */
+ /* fn pow(f32, f32) -> f32 */
+ /* fn pow<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[335],
+ },
+ {
+ /* [61] */
+ /* fn radians(f32) -> f32 */
+ /* fn radians<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[337],
+ },
+ {
+ /* [62] */
+ /* fn reflect<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[459],
+ },
+ {
+ /* [63] */
+ /* fn refract<N : num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32> */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[458],
+ },
+ {
+ /* [64] */
+ /* fn reverseBits<T : iu32>(T) -> T */
+ /* fn reverseBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[343],
+ },
+ {
+ /* [65] */
+ /* fn round(f32) -> f32 */
+ /* fn round<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[345],
+ },
+ {
+ /* [66] */
+ /* fn select<T : scalar_no_f16>(T, T, bool) -> T */
+ /* fn select<T : scalar_no_f16, N : num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T> */
+ /* fn select<N : num, T : scalar_no_f16>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T> */
+ /* num overloads */ 3,
+ /* overloads */ &kOverloads[284],
+ },
+ {
+ /* [67] */
+ /* fn sign(f32) -> f32 */
+ /* fn sign<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[349],
+ },
+ {
+ /* [68] */
+ /* fn sin(f32) -> f32 */
+ /* fn sin<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[351],
+ },
+ {
+ /* [69] */
+ /* fn sinh(f32) -> f32 */
+ /* fn sinh<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[353],
+ },
+ {
+ /* [70] */
+ /* fn smoothstep(f32, f32, f32) -> f32 */
+ /* fn smoothstep<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[355],
+ },
+ {
+ /* [71] */
+ /* fn sqrt(f32) -> f32 */
+ /* fn sqrt<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[357],
+ },
+ {
+ /* [72] */
+ /* fn step(f32, f32) -> f32 */
+ /* fn step<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[359],
+ },
+ {
+ /* [73] */
+ /* fn storageBarrier() */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[450],
+ },
+ {
+ /* [74] */
+ /* fn tan(f32) -> f32 */
+ /* fn tan<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[363],
+ },
+ {
+ /* [75] */
+ /* fn tanh(f32) -> f32 */
+ /* fn tanh<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[365],
},
{
/* [76] */
- /* fn unpack2x16snorm(u32) -> vec2<f32> */
+ /* fn transpose<M : num, N : num>(mat<M, N, f32>) -> mat<N, M, f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[407],
+ /* overloads */ &kOverloads[457],
},
{
/* [77] */
- /* fn unpack2x16unorm(u32) -> vec2<f32> */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[423],
+ /* fn trunc(f32) -> f32 */
+ /* fn trunc<N : num>(vec<N, f32>) -> vec<N, f32> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[369],
},
{
/* [78] */
- /* fn unpack4x8snorm(u32) -> vec4<f32> */
+ /* fn unpack2x16float(u32) -> vec2<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[422],
+ /* overloads */ &kOverloads[456],
},
{
/* [79] */
- /* fn unpack4x8unorm(u32) -> vec4<f32> */
+ /* fn unpack2x16snorm(u32) -> vec2<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[421],
+ /* overloads */ &kOverloads[455],
},
{
/* [80] */
- /* fn workgroupBarrier() */
+ /* fn unpack2x16unorm(u32) -> vec2<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[420],
+ /* overloads */ &kOverloads[454],
},
{
/* [81] */
+ /* fn unpack4x8snorm(u32) -> vec4<f32> */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[453],
+ },
+ {
+ /* [82] */
+ /* fn unpack4x8unorm(u32) -> vec4<f32> */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[452],
+ },
+ {
+ /* [83] */
+ /* fn workgroupBarrier() */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[451],
+ },
+ {
+ /* [84] */
/* fn textureDimensions<T : fiu32>(texture: texture_1d<T>) -> i32 */
/* fn textureDimensions<T : fiu32>(texture: texture_1d<T>, level: i32) -> i32 */
/* fn textureDimensions<T : fiu32>(texture: texture_2d<T>) -> vec2<i32> */
@@ -13539,7 +14275,7 @@
/* overloads */ &kOverloads[0],
},
{
- /* [82] */
+ /* [85] */
/* fn textureGather<T : fiu32>(@const component: i32, texture: texture_2d<T>, sampler: sampler, coords: vec2<f32>) -> vec4<T> */
/* fn textureGather<T : fiu32>(@const component: i32, texture: texture_2d<T>, sampler: sampler, coords: vec2<f32>, @const offset: vec2<i32>) -> vec4<T> */
/* fn textureGather<T : fiu32>(@const component: i32, texture: texture_2d_array<T>, sampler: sampler, coords: vec2<f32>, array_index: i32) -> vec4<T> */
@@ -13553,10 +14289,10 @@
/* fn textureGather(texture: texture_depth_cube, sampler: sampler, coords: vec3<f32>) -> vec4<f32> */
/* fn textureGather(texture: texture_depth_cube_array, sampler: sampler, coords: vec3<f32>, array_index: i32) -> vec4<f32> */
/* num overloads */ 12,
- /* overloads */ &kOverloads[71],
+ /* overloads */ &kOverloads[72],
},
{
- /* [83] */
+ /* [86] */
/* 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(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: i32, depth_ref: f32) -> vec4<f32> */
@@ -13564,20 +14300,20 @@
/* fn textureGatherCompare(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3<f32>, depth_ref: f32) -> vec4<f32> */
/* fn textureGatherCompare(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3<f32>, array_index: i32, depth_ref: f32) -> vec4<f32> */
/* num overloads */ 6,
- /* overloads */ &kOverloads[157],
+ /* overloads */ &kOverloads[235],
},
{
- /* [84] */
+ /* [87] */
/* fn textureNumLayers<T : fiu32>(texture: texture_2d_array<T>) -> i32 */
/* fn textureNumLayers<T : fiu32>(texture: texture_cube_array<T>) -> i32 */
/* fn textureNumLayers(texture: texture_depth_2d_array) -> i32 */
/* fn textureNumLayers(texture: texture_depth_cube_array) -> i32 */
/* fn textureNumLayers<F : texel_format, A : write_only>(texture: texture_storage_2d_array<F, A>) -> i32 */
/* num overloads */ 5,
- /* overloads */ &kOverloads[185],
+ /* overloads */ &kOverloads[246],
},
{
- /* [85] */
+ /* [88] */
/* fn textureNumLevels<T : fiu32>(texture: texture_1d<T>) -> i32 */
/* fn textureNumLevels<T : fiu32>(texture: texture_2d<T>) -> i32 */
/* fn textureNumLevels<T : fiu32>(texture: texture_2d_array<T>) -> i32 */
@@ -13589,17 +14325,17 @@
/* fn textureNumLevels(texture: texture_depth_cube) -> i32 */
/* fn textureNumLevels(texture: texture_depth_cube_array) -> i32 */
/* num overloads */ 10,
- /* overloads */ &kOverloads[105],
+ /* overloads */ &kOverloads[107],
},
{
- /* [86] */
+ /* [89] */
/* fn textureNumSamples<T : fiu32>(texture: texture_multisampled_2d<T>) -> i32 */
/* fn textureNumSamples(texture: texture_depth_multisampled_2d) -> i32 */
/* num overloads */ 2,
- /* overloads */ &kOverloads[365],
+ /* overloads */ &kOverloads[393],
},
{
- /* [87] */
+ /* [90] */
/* 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> */
@@ -13616,10 +14352,10 @@
/* fn textureSample(texture: texture_depth_cube, sampler: sampler, coords: vec3<f32>) -> f32 */
/* fn textureSample(texture: texture_depth_cube_array, sampler: sampler, coords: vec3<f32>, array_index: i32) -> f32 */
/* num overloads */ 15,
- /* overloads */ &kOverloads[27],
+ /* overloads */ &kOverloads[42],
},
{
- /* [88] */
+ /* [91] */
/* 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(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32, bias: f32) -> vec4<f32> */
@@ -13629,10 +14365,10 @@
/* fn textureSampleBias(texture: texture_cube<f32>, sampler: sampler, coords: vec3<f32>, bias: f32) -> vec4<f32> */
/* fn textureSampleBias(texture: texture_cube_array<f32>, sampler: sampler, coords: vec3<f32>, array_index: i32, bias: f32) -> vec4<f32> */
/* num overloads */ 8,
- /* overloads */ &kOverloads[133],
+ /* overloads */ &kOverloads[152],
},
{
- /* [89] */
+ /* [92] */
/* 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(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: i32, depth_ref: f32) -> f32 */
@@ -13640,10 +14376,10 @@
/* fn textureSampleCompare(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3<f32>, depth_ref: f32) -> f32 */
/* fn textureSampleCompare(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3<f32>, array_index: i32, depth_ref: f32) -> f32 */
/* num overloads */ 6,
- /* overloads */ &kOverloads[163],
+ /* overloads */ &kOverloads[223],
},
{
- /* [90] */
+ /* [93] */
/* 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(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2<f32>, array_index: i32, depth_ref: f32) -> f32 */
@@ -13651,10 +14387,10 @@
/* fn textureSampleCompareLevel(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3<f32>, depth_ref: f32) -> f32 */
/* fn textureSampleCompareLevel(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3<f32>, array_index: i32, depth_ref: f32) -> f32 */
/* num overloads */ 6,
- /* overloads */ &kOverloads[169],
+ /* overloads */ &kOverloads[229],
},
{
- /* [91] */
+ /* [94] */
/* 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(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32, ddx: vec2<f32>, ddy: vec2<f32>) -> vec4<f32> */
@@ -13664,10 +14400,10 @@
/* fn textureSampleGrad(texture: texture_cube<f32>, sampler: sampler, coords: vec3<f32>, ddx: vec3<f32>, ddy: vec3<f32>) -> vec4<f32> */
/* fn textureSampleGrad(texture: texture_cube_array<f32>, sampler: sampler, coords: vec3<f32>, array_index: i32, ddx: vec3<f32>, ddy: vec3<f32>) -> vec4<f32> */
/* num overloads */ 8,
- /* overloads */ &kOverloads[141],
+ /* overloads */ &kOverloads[144],
},
{
- /* [92] */
+ /* [95] */
/* 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(texture: texture_2d_array<f32>, sampler: sampler, coords: vec2<f32>, array_index: i32, level: f32) -> vec4<f32> */
@@ -13684,10 +14420,10 @@
/* fn textureSampleLevel(texture: texture_depth_cube_array, sampler: sampler, coords: vec3<f32>, array_index: i32, level: i32) -> f32 */
/* fn textureSampleLevel(texture: texture_external, sampler: sampler, coords: vec2<f32>) -> vec4<f32> */
/* num overloads */ 15,
- /* overloads */ &kOverloads[42],
+ /* overloads */ &kOverloads[57],
},
{
- /* [93] */
+ /* [96] */
/* fn textureStore(texture: texture_storage_1d<f32_texel_format, write>, coords: i32, value: vec4<f32>) */
/* fn textureStore(texture: texture_storage_2d<f32_texel_format, write>, coords: vec2<i32>, value: vec4<f32>) */
/* fn textureStore(texture: texture_storage_2d_array<f32_texel_format, write>, coords: vec2<i32>, array_index: i32, value: vec4<f32>) */
@@ -13701,10 +14437,10 @@
/* fn textureStore(texture: texture_storage_2d_array<u32_texel_format, write>, coords: vec2<i32>, array_index: i32, value: vec4<u32>) */
/* fn textureStore(texture: texture_storage_3d<u32_texel_format, write>, coords: vec3<i32>, value: vec4<u32>) */
/* num overloads */ 12,
- /* overloads */ &kOverloads[83],
+ /* overloads */ &kOverloads[84],
},
{
- /* [94] */
+ /* [97] */
/* fn textureLoad<T : fiu32>(texture: texture_1d<T>, coords: i32, level: i32) -> vec4<T> */
/* fn textureLoad<T : fiu32>(texture: texture_2d<T>, coords: vec2<i32>, level: i32) -> vec4<T> */
/* fn textureLoad<T : fiu32>(texture: texture_2d_array<T>, coords: vec2<i32>, array_index: i32, level: i32) -> vec4<T> */
@@ -13715,73 +14451,73 @@
/* fn textureLoad(texture: texture_depth_multisampled_2d, coords: vec2<i32>, sample_index: i32) -> f32 */
/* fn textureLoad(texture: texture_external, coords: vec2<i32>) -> vec4<f32> */
/* num overloads */ 9,
- /* overloads */ &kOverloads[115],
- },
- {
- /* [95] */
- /* fn atomicLoad<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>) -> T */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[416],
- },
- {
- /* [96] */
- /* fn atomicStore<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[415],
- },
- {
- /* [97] */
- /* fn atomicAdd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[414],
+ /* overloads */ &kOverloads[126],
},
{
/* [98] */
- /* fn atomicSub<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* fn atomicLoad<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[413],
+ /* overloads */ &kOverloads[449],
},
{
/* [99] */
- /* fn atomicMax<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* fn atomicStore<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) */
/* num overloads */ 1,
- /* overloads */ &kOverloads[412],
+ /* overloads */ &kOverloads[448],
},
{
/* [100] */
- /* fn atomicMin<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* fn atomicAdd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[411],
+ /* overloads */ &kOverloads[445],
},
{
/* [101] */
- /* fn atomicAnd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* fn atomicSub<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[410],
+ /* overloads */ &kOverloads[444],
},
{
/* [102] */
- /* fn atomicOr<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* fn atomicMax<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[409],
+ /* overloads */ &kOverloads[443],
},
{
/* [103] */
- /* fn atomicXor<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* fn atomicMin<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[408],
+ /* overloads */ &kOverloads[442],
},
{
/* [104] */
- /* fn atomicExchange<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* fn atomicAnd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[424],
+ /* overloads */ &kOverloads[441],
},
{
/* [105] */
+ /* fn atomicOr<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[440],
+ },
+ {
+ /* [106] */
+ /* fn atomicXor<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[439],
+ },
+ {
+ /* [107] */
+ /* fn atomicExchange<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[438],
+ },
+ {
+ /* [108] */
/* 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[442],
+ /* overloads */ &kOverloads[437],
},
};
@@ -13791,21 +14527,21 @@
/* op !(bool) -> bool */
/* op !<N : num>(vec<N, bool>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[269],
+ /* overloads */ &kOverloads[433],
},
{
/* [1] */
/* op ~<T : iu32>(T) -> T */
/* op ~<T : iu32, N : num>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[401],
+ /* overloads */ &kOverloads[293],
},
{
/* [2] */
/* op -<T : fi32>(T) -> T */
/* op -<T : fi32, N : num>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[399],
+ /* overloads */ &kOverloads[431],
},
};
constexpr uint8_t kUnaryOperatorNot = 0;
@@ -13821,7 +14557,7 @@
/* op +<T : fiu32, N : num>(T, vec<N, T>) -> vec<N, T> */
/* op +<N : num, M : num>(mat<N, M, f32>, mat<N, M, f32>) -> mat<N, M, f32> */
/* num overloads */ 5,
- /* overloads */ &kOverloads[215],
+ /* overloads */ &kOverloads[251],
},
{
/* [1] */
@@ -13831,7 +14567,7 @@
/* op -<T : fiu32, N : num>(T, vec<N, T>) -> vec<N, T> */
/* op -<N : num, M : num>(mat<N, M, f32>, mat<N, M, f32>) -> mat<N, M, f32> */
/* num overloads */ 5,
- /* overloads */ &kOverloads[210],
+ /* overloads */ &kOverloads[241],
},
{
/* [2] */
@@ -13845,7 +14581,7 @@
/* op *<C : num, R : num>(vec<R, f32>, mat<C, R, f32>) -> vec<C, f32> */
/* op *<K : num, C : num, R : num>(mat<K, R, f32>, mat<C, K, f32>) -> mat<C, R, f32> */
/* num overloads */ 9,
- /* overloads */ &kOverloads[124],
+ /* overloads */ &kOverloads[117],
},
{
/* [3] */
@@ -13854,7 +14590,7 @@
/* op /<T : fiu32, N : num>(vec<N, T>, T) -> vec<N, T> */
/* op /<T : fiu32, N : num>(T, vec<N, T>) -> vec<N, T> */
/* num overloads */ 4,
- /* overloads */ &kOverloads[243],
+ /* overloads */ &kOverloads[268],
},
{
/* [4] */
@@ -13863,14 +14599,14 @@
/* op %<T : fiu32, N : num>(vec<N, T>, T) -> vec<N, T> */
/* op %<T : fiu32, N : num>(T, vec<N, T>) -> vec<N, T> */
/* num overloads */ 4,
- /* overloads */ &kOverloads[239],
+ /* overloads */ &kOverloads[256],
},
{
/* [5] */
/* op ^<T : iu32>(T, T) -> T */
/* op ^<T : iu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[387],
+ /* overloads */ &kOverloads[419],
},
{
/* [6] */
@@ -13879,7 +14615,7 @@
/* op &<T : iu32>(T, T) -> T */
/* op &<T : iu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 4,
- /* overloads */ &kOverloads[235],
+ /* overloads */ &kOverloads[260],
},
{
/* [7] */
@@ -13888,75 +14624,75 @@
/* op |<T : iu32>(T, T) -> T */
/* op |<T : iu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 4,
- /* overloads */ &kOverloads[247],
+ /* overloads */ &kOverloads[264],
},
{
/* [8] */
/* op &&(bool, bool) -> bool */
/* num overloads */ 1,
- /* overloads */ &kOverloads[417],
+ /* overloads */ &kOverloads[446],
},
{
/* [9] */
/* op ||(bool, bool) -> bool */
/* num overloads */ 1,
- /* overloads */ &kOverloads[418],
+ /* 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[369],
+ /* overloads */ &kOverloads[413],
},
{
/* [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[353],
+ /* overloads */ &kOverloads[411],
},
{
/* [12] */
/* op <<T : fiu32>(T, T) -> bool */
/* op <<T : fiu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[351],
+ /* overloads */ &kOverloads[397],
},
{
/* [13] */
/* op ><T : fiu32>(T, T) -> bool */
/* op ><T : fiu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[349],
+ /* overloads */ &kOverloads[381],
},
{
/* [14] */
/* op <=<T : fiu32>(T, T) -> bool */
/* op <=<T : fiu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[347],
+ /* overloads */ &kOverloads[379],
},
{
/* [15] */
/* op >=<T : fiu32>(T, T) -> bool */
/* op >=<T : fiu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[345],
+ /* overloads */ &kOverloads[377],
},
{
/* [16] */
/* 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[405],
+ /* overloads */ &kOverloads[435],
},
{
/* [17] */
/* 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[339],
+ /* overloads */ &kOverloads[373],
},
};
constexpr uint8_t kBinaryOperatorPlus = 0;
@@ -13985,7 +14721,7 @@
/* ctor i32(i32) -> i32 */
/* conv i32<T : scalar_no_i32>(T) -> i32 */
/* num overloads */ 3,
- /* overloads */ &kOverloads[254],
+ /* overloads */ &kOverloads[272],
},
{
/* [1] */
@@ -13993,7 +14729,7 @@
/* ctor u32(u32) -> u32 */
/* conv u32<T : scalar_no_u32>(T) -> u32 */
/* num overloads */ 3,
- /* overloads */ &kOverloads[257],
+ /* overloads */ &kOverloads[287],
},
{
/* [2] */
@@ -14001,31 +14737,40 @@
/* ctor f32(f32) -> f32 */
/* conv f32<T : scalar_no_f32>(T) -> f32 */
/* num overloads */ 3,
- /* overloads */ &kOverloads[260],
+ /* overloads */ &kOverloads[281],
},
{
/* [3] */
+ /* ctor f16() -> f16 */
+ /* ctor f16(f16) -> f16 */
+ /* conv f16<T : scalar_no_f16>(T) -> f16 */
+ /* num overloads */ 3,
+ /* overloads */ &kOverloads[278],
+ },
+ {
+ /* [4] */
/* ctor bool() -> bool */
/* ctor bool(bool) -> bool */
/* conv bool<T : scalar_no_bool>(T) -> bool */
/* num overloads */ 3,
- /* overloads */ &kOverloads[263],
+ /* overloads */ &kOverloads[275],
},
{
- /* [4] */
+ /* [5] */
/* ctor vec2<T : scalar>() -> vec2<T> */
/* ctor vec2<T : scalar>(vec2<T>) -> vec2<T> */
/* ctor vec2<T : abstract_or_scalar>(T) -> vec2<T> */
/* ctor vec2<T : abstract_or_scalar>(x: T, y: T) -> vec2<T> */
/* conv vec2<T : f32, U : scalar_no_f32>(vec2<U>) -> vec2<f32> */
+ /* conv vec2<T : f16, U : scalar_no_f16>(vec2<U>) -> vec2<f16> */
/* conv vec2<T : i32, U : scalar_no_i32>(vec2<U>) -> vec2<i32> */
/* conv vec2<T : u32, U : scalar_no_u32>(vec2<U>) -> vec2<u32> */
/* conv vec2<T : bool, U : scalar_no_bool>(vec2<U>) -> vec2<bool> */
- /* num overloads */ 8,
- /* overloads */ &kOverloads[149],
+ /* num overloads */ 9,
+ /* overloads */ &kOverloads[135],
},
{
- /* [5] */
+ /* [6] */
/* ctor vec3<T : scalar>() -> vec3<T> */
/* ctor vec3<T : scalar>(vec3<T>) -> vec3<T> */
/* ctor vec3<T : abstract_or_scalar>(T) -> vec3<T> */
@@ -14033,14 +14778,15 @@
/* ctor vec3<T : abstract_or_scalar>(xy: vec2<T>, z: T) -> vec3<T> */
/* ctor vec3<T : abstract_or_scalar>(x: T, yz: vec2<T>) -> vec3<T> */
/* conv vec3<T : f32, U : scalar_no_f32>(vec3<U>) -> vec3<f32> */
+ /* conv vec3<T : f16, U : scalar_no_f16>(vec3<U>) -> vec3<f16> */
/* conv vec3<T : i32, U : scalar_no_i32>(vec3<U>) -> vec3<i32> */
/* conv vec3<T : u32, U : scalar_no_u32>(vec3<U>) -> vec3<u32> */
/* conv vec3<T : bool, U : scalar_no_bool>(vec3<U>) -> vec3<bool> */
- /* num overloads */ 10,
- /* overloads */ &kOverloads[95],
+ /* num overloads */ 11,
+ /* overloads */ &kOverloads[96],
},
{
- /* [6] */
+ /* [7] */
/* ctor vec4<T : scalar>() -> vec4<T> */
/* ctor vec4<T : scalar>(vec4<T>) -> vec4<T> */
/* ctor vec4<T : abstract_or_scalar>(T) -> vec4<T> */
@@ -14052,101 +14798,120 @@
/* ctor vec4<T : abstract_or_scalar>(xyz: vec3<T>, w: T) -> vec4<T> */
/* ctor vec4<T : abstract_or_scalar>(x: T, zyw: vec3<T>) -> vec4<T> */
/* conv vec4<T : f32, U : scalar_no_f32>(vec4<U>) -> vec4<f32> */
+ /* conv vec4<T : f16, U : scalar_no_f16>(vec4<U>) -> vec4<f16> */
/* conv vec4<T : i32, U : scalar_no_i32>(vec4<U>) -> vec4<i32> */
/* conv vec4<T : u32, U : scalar_no_u32>(vec4<U>) -> vec4<u32> */
/* conv vec4<T : bool, U : scalar_no_bool>(vec4<U>) -> vec4<bool> */
- /* num overloads */ 14,
- /* overloads */ &kOverloads[57],
- },
- {
- /* [7] */
- /* ctor mat2x2() -> mat2x2<f32> */
- /* ctor mat2x2<f32>(mat2x2<f32>) -> mat2x2<f32> */
- /* ctor mat2x2<T : af_f32>(T) -> mat2x2<T> */
- /* ctor mat2x2<T : af_f32>(T, T, T, T) -> mat2x2<T> */
- /* ctor mat2x2<T : af_f32>(vec2<T>, vec2<T>) -> mat2x2<T> */
- /* num overloads */ 5,
- /* overloads */ &kOverloads[190],
+ /* num overloads */ 15,
+ /* overloads */ &kOverloads[27],
},
{
/* [8] */
- /* ctor mat2x3() -> mat2x3<f32> */
- /* ctor mat2x3<f32>(mat2x3<f32>) -> mat2x3<f32> */
- /* ctor mat2x3<T : af_f32>(T) -> mat2x3<T> */
- /* ctor mat2x3<T : af_f32>(T, T, T, T, T, T) -> mat2x3<T> */
- /* ctor mat2x3<T : af_f32>(vec3<T>, vec3<T>) -> mat2x3<T> */
- /* num overloads */ 5,
- /* overloads */ &kOverloads[180],
+ /* ctor mat2x2<T : f32f16>() -> mat2x2<T> */
+ /* ctor mat2x2<T : f32f16>(mat2x2<T>) -> mat2x2<T> */
+ /* ctor mat2x2<T : af_f32>(T) -> mat2x2<T> */
+ /* ctor mat2x2<T : af_f32f16>(T, T, T, T) -> mat2x2<T> */
+ /* ctor mat2x2<T : af_f32f16>(vec2<T>, vec2<T>) -> mat2x2<T> */
+ /* conv mat2x2<T : f16>(mat2x2<f32>) -> mat2x2<f16> */
+ /* conv mat2x2<T : f32>(mat2x2<f16>) -> mat2x2<f32> */
+ /* num overloads */ 7,
+ /* overloads */ &kOverloads[181],
},
{
/* [9] */
- /* ctor mat2x4() -> mat2x4<f32> */
- /* ctor mat2x4<f32>(mat2x4<f32>) -> mat2x4<f32> */
- /* ctor mat2x4<T : af_f32>(T) -> mat2x4<T> */
- /* ctor mat2x4<T : af_f32>(T, T, T, T, T, T, T, T) -> mat2x4<T> */
- /* ctor mat2x4<T : af_f32>(vec4<T>, vec4<T>) -> mat2x4<T> */
- /* num overloads */ 5,
- /* overloads */ &kOverloads[225],
+ /* ctor mat2x3<T : f32f16>() -> mat2x3<T> */
+ /* ctor mat2x3<T : f32f16>(mat2x3<T>) -> mat2x3<T> */
+ /* ctor mat2x3<T : af_f32>(T) -> mat2x3<T> */
+ /* ctor mat2x3<T : af_f32f16>(T, T, T, T, T, T) -> mat2x3<T> */
+ /* ctor mat2x3<T : af_f32f16>(vec3<T>, vec3<T>) -> mat2x3<T> */
+ /* conv mat2x3<T : f16>(mat2x3<f32>) -> mat2x3<f16> */
+ /* conv mat2x3<T : f32>(mat2x3<f16>) -> mat2x3<f32> */
+ /* num overloads */ 7,
+ /* overloads */ &kOverloads[202],
},
{
/* [10] */
- /* ctor mat3x2() -> mat3x2<f32> */
- /* ctor mat3x2<f32>(mat3x2<f32>) -> mat3x2<f32> */
- /* ctor mat3x2<T : af_f32>(T) -> mat3x2<T> */
- /* ctor mat3x2<T : af_f32>(T, T, T, T, T, T) -> mat3x2<T> */
- /* ctor mat3x2<T : af_f32>(vec2<T>, vec2<T>, vec2<T>) -> mat3x2<T> */
- /* num overloads */ 5,
- /* overloads */ &kOverloads[200],
+ /* ctor mat2x4<T : f32f16>() -> mat2x4<T> */
+ /* ctor mat2x4<T : f32f16>(mat2x4<T>) -> mat2x4<T> */
+ /* ctor mat2x4<T : af_f32>(T) -> mat2x4<T> */
+ /* ctor mat2x4<T : af_f32f16>(T, T, T, T, T, T, T, T) -> mat2x4<T> */
+ /* ctor mat2x4<T : af_f32f16>(vec4<T>, vec4<T>) -> mat2x4<T> */
+ /* conv mat2x4<T : f16>(mat2x4<f32>) -> mat2x4<f16> */
+ /* conv mat2x4<T : f32>(mat2x4<f16>) -> mat2x4<f32> */
+ /* num overloads */ 7,
+ /* overloads */ &kOverloads[174],
},
{
/* [11] */
- /* ctor mat3x3() -> mat3x3<f32> */
- /* ctor mat3x3<f32>(mat3x3<f32>) -> mat3x3<f32> */
- /* ctor mat3x3<T : af_f32>(T) -> mat3x3<T> */
- /* ctor mat3x3<T : af_f32>(T, T, T, T, T, T, T, T, T) -> mat3x3<T> */
- /* ctor mat3x3<T : af_f32>(vec3<T>, vec3<T>, vec3<T>) -> mat3x3<T> */
- /* num overloads */ 5,
+ /* ctor mat3x2<T : f32f16>() -> mat3x2<T> */
+ /* ctor mat3x2<T : f32f16>(mat3x2<T>) -> mat3x2<T> */
+ /* ctor mat3x2<T : af_f32>(T) -> mat3x2<T> */
+ /* ctor mat3x2<T : af_f32f16>(T, T, T, T, T, T) -> mat3x2<T> */
+ /* ctor mat3x2<T : af_f32f16>(vec2<T>, vec2<T>, vec2<T>) -> mat3x2<T> */
+ /* conv mat3x2<T : f16>(mat3x2<f32>) -> mat3x2<f16> */
+ /* conv mat3x2<T : f32>(mat3x2<f16>) -> mat3x2<f32> */
+ /* num overloads */ 7,
/* overloads */ &kOverloads[195],
},
{
/* [12] */
- /* ctor mat3x4() -> mat3x4<f32> */
- /* ctor mat3x4<f32>(mat3x4<f32>) -> mat3x4<f32> */
- /* ctor mat3x4<T : af_f32>(T) -> mat3x4<T> */
- /* ctor mat3x4<T : af_f32>(T, T, T, T, T, T, T, T, T, T, T, T) -> mat3x4<T> */
- /* ctor mat3x4<T : af_f32>(vec4<T>, vec4<T>, vec4<T>) -> mat3x4<T> */
- /* num overloads */ 5,
- /* overloads */ &kOverloads[230],
+ /* ctor mat3x3<T : f32f16>() -> mat3x3<T> */
+ /* ctor mat3x3<T : f32f16>(mat3x3<T>) -> mat3x3<T> */
+ /* ctor mat3x3<T : af_f32>(T) -> mat3x3<T> */
+ /* ctor mat3x3<T : af_f32f16>(T, T, T, T, T, T, T, T, T) -> mat3x3<T> */
+ /* ctor mat3x3<T : af_f32f16>(vec3<T>, vec3<T>, vec3<T>) -> mat3x3<T> */
+ /* conv mat3x3<T : f16>(mat3x3<f32>) -> mat3x3<f16> */
+ /* conv mat3x3<T : f32>(mat3x3<f16>) -> mat3x3<f32> */
+ /* num overloads */ 7,
+ /* overloads */ &kOverloads[188],
},
{
/* [13] */
- /* ctor mat4x2() -> mat4x2<f32> */
- /* ctor mat4x2<f32>(mat4x2<f32>) -> mat4x2<f32> */
- /* ctor mat4x2<T : af_f32>(T) -> mat4x2<T> */
- /* ctor mat4x2<T : af_f32>(T, T, T, T, T, T, T, T) -> mat4x2<T> */
- /* ctor mat4x2<T : af_f32>(vec2<T>, vec2<T>, vec2<T>, vec2<T>) -> mat4x2<T> */
- /* num overloads */ 5,
- /* overloads */ &kOverloads[175],
+ /* ctor mat3x4<T : f32f16>() -> mat3x4<T> */
+ /* ctor mat3x4<T : f32f16>(mat3x4<T>) -> mat3x4<T> */
+ /* ctor mat3x4<T : af_f32>(T) -> mat3x4<T> */
+ /* ctor mat3x4<T : af_f32f16>(T, T, T, T, T, T, T, T, T, T, T, T) -> mat3x4<T> */
+ /* ctor mat3x4<T : af_f32f16>(vec4<T>, vec4<T>, vec4<T>) -> mat3x4<T> */
+ /* conv mat3x4<T : f16>(mat3x4<f32>) -> mat3x4<f16> */
+ /* conv mat3x4<T : f32>(mat3x4<f16>) -> mat3x4<f32> */
+ /* num overloads */ 7,
+ /* overloads */ &kOverloads[216],
},
{
/* [14] */
- /* ctor mat4x3() -> mat4x3<f32> */
- /* ctor mat4x3<f32>(mat4x3<f32>) -> mat4x3<f32> */
- /* ctor mat4x3<T : af_f32>(T) -> mat4x3<T> */
- /* ctor mat4x3<T : af_f32>(T, T, T, T, T, T, T, T, T, T, T, T) -> mat4x3<T> */
- /* ctor mat4x3<T : af_f32>(vec3<T>, vec3<T>, vec3<T>, vec3<T>) -> mat4x3<T> */
- /* num overloads */ 5,
- /* overloads */ &kOverloads[205],
+ /* ctor mat4x2<T : f32f16>() -> mat4x2<T> */
+ /* ctor mat4x2<T : f32f16>(mat4x2<T>) -> mat4x2<T> */
+ /* ctor mat4x2<T : af_f32>(T) -> mat4x2<T> */
+ /* ctor mat4x2<T : af_f32f16>(T, T, T, T, T, T, T, T) -> mat4x2<T> */
+ /* ctor mat4x2<T : af_f32f16>(vec2<T>, vec2<T>, vec2<T>, vec2<T>) -> mat4x2<T> */
+ /* conv mat4x2<T : f16>(mat4x2<f32>) -> mat4x2<f16> */
+ /* conv mat4x2<T : f32>(mat4x2<f16>) -> mat4x2<f32> */
+ /* num overloads */ 7,
+ /* overloads */ &kOverloads[167],
},
{
/* [15] */
- /* ctor mat4x4() -> mat4x4<f32> */
- /* ctor mat4x4<f32>(mat4x4<f32>) -> mat4x4<f32> */
+ /* ctor mat4x3<T : f32f16>() -> mat4x3<T> */
+ /* ctor mat4x3<T : f32f16>(mat4x3<T>) -> mat4x3<T> */
+ /* ctor mat4x3<T : af_f32>(T) -> mat4x3<T> */
+ /* ctor mat4x3<T : af_f32f16>(T, T, T, T, T, T, T, T, T, T, T, T) -> mat4x3<T> */
+ /* ctor mat4x3<T : af_f32f16>(vec3<T>, vec3<T>, vec3<T>, vec3<T>) -> mat4x3<T> */
+ /* conv mat4x3<T : f16>(mat4x3<f32>) -> mat4x3<f16> */
+ /* conv mat4x3<T : f32>(mat4x3<f16>) -> mat4x3<f32> */
+ /* num overloads */ 7,
+ /* overloads */ &kOverloads[209],
+ },
+ {
+ /* [16] */
+ /* ctor mat4x4<T : f32f16>() -> mat4x4<T> */
+ /* ctor mat4x4<T : f32f16>(mat4x4<T>) -> mat4x4<T> */
/* ctor mat4x4<T : af_f32>(T) -> mat4x4<T> */
- /* ctor mat4x4<T : af_f32>(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) -> mat4x4<T> */
- /* ctor mat4x4<T : af_f32>(vec4<T>, vec4<T>, vec4<T>, vec4<T>) -> mat4x4<T> */
- /* num overloads */ 5,
- /* overloads */ &kOverloads[220],
+ /* ctor mat4x4<T : af_f32f16>(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) -> mat4x4<T> */
+ /* ctor mat4x4<T : af_f32f16>(vec4<T>, vec4<T>, vec4<T>, vec4<T>) -> mat4x4<T> */
+ /* conv mat4x4<T : f16>(mat4x4<f32>) -> mat4x4<f16> */
+ /* conv mat4x4<T : f32>(mat4x4<f16>) -> mat4x4<f32> */
+ /* num overloads */ 7,
+ /* overloads */ &kOverloads[160],
},
};
diff --git a/src/tint/resolver/intrinsic_table_test.cc b/src/tint/resolver/intrinsic_table_test.cc
index e2c651e..e2c2247 100644
--- a/src/tint/resolver/intrinsic_table_test.cc
+++ b/src/tint/resolver/intrinsic_table_test.cc
@@ -709,18 +709,19 @@
EXPECT_EQ(Diagnostics().str(), R"(12:34 error: no matching constructor for vec3(i32, f32, i32)
6 candidate constructors:
- vec3(x: T, y: T, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3(xy: vec2<T>, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3(x: T, yz: vec2<T>) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3(T) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3(vec3<T>) -> vec3<T> where: T is f32, i32, u32 or bool
- vec3() -> vec3<T> where: T is f32, i32, u32 or bool
+ vec3(x: T, y: T, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3(xy: vec2<T>, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3(x: T, yz: vec2<T>) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3(T) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3(vec3<T>) -> vec3<T> where: T is f32, f16, i32, u32 or bool
+ vec3() -> vec3<T> where: T is f32, f16, i32, u32 or bool
-4 candidate conversions:
- vec3(vec3<U>) -> vec3<f32> where: T is f32, U is i32, u32 or bool
- vec3(vec3<U>) -> vec3<i32> where: T is i32, U is f32, u32 or bool
- vec3(vec3<U>) -> vec3<u32> where: T is u32, U is f32, i32 or bool
- vec3(vec3<U>) -> vec3<bool> where: T is bool, U is f32, i32 or u32
+5 candidate conversions:
+ vec3(vec3<U>) -> vec3<f32> where: T is f32, U is i32, f16, u32 or bool
+ vec3(vec3<U>) -> vec3<f16> where: T is f16, U is f32, i32, u32 or bool
+ vec3(vec3<U>) -> vec3<i32> where: T is i32, U is f32, f16, u32 or bool
+ vec3(vec3<U>) -> vec3<u32> where: T is u32, U is f32, f16, i32 or bool
+ vec3(vec3<U>) -> vec3<bool> where: T is bool, U is f32, f16, i32 or u32
)");
}
@@ -733,18 +734,19 @@
R"(12:34 error: no matching constructor for vec3<i32>(i32, f32, i32)
6 candidate constructors:
- vec3(x: T, y: T, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3(x: T, yz: vec2<T>) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3(T) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3(xy: vec2<T>, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3(vec3<T>) -> vec3<T> where: T is f32, i32, u32 or bool
- vec3() -> vec3<T> where: T is f32, i32, u32 or bool
+ vec3(x: T, y: T, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3(x: T, yz: vec2<T>) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3(T) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3(xy: vec2<T>, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3(vec3<T>) -> vec3<T> where: T is f32, f16, i32, u32 or bool
+ vec3() -> vec3<T> where: T is f32, f16, i32, u32 or bool
-4 candidate conversions:
- vec3(vec3<U>) -> vec3<f32> where: T is f32, U is i32, u32 or bool
- vec3(vec3<U>) -> vec3<i32> where: T is i32, U is f32, u32 or bool
- vec3(vec3<U>) -> vec3<u32> where: T is u32, U is f32, i32 or bool
- vec3(vec3<U>) -> vec3<bool> where: T is bool, U is f32, i32 or u32
+5 candidate conversions:
+ vec3(vec3<U>) -> vec3<f32> where: T is f32, U is i32, f16, u32 or bool
+ vec3(vec3<U>) -> vec3<f16> where: T is f16, U is f32, i32, u32 or bool
+ vec3(vec3<U>) -> vec3<i32> where: T is i32, U is f32, f16, u32 or bool
+ vec3(vec3<U>) -> vec3<u32> where: T is u32, U is f32, f16, i32 or bool
+ vec3(vec3<U>) -> vec3<bool> where: T is bool, U is f32, f16, i32 or u32
)");
}
@@ -770,18 +772,19 @@
R"(12:34 error: no matching constructor for vec3<f32>(array<u32>)
6 candidate constructors:
- vec3(vec3<T>) -> vec3<T> where: T is f32, i32, u32 or bool
- vec3(T) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3() -> vec3<T> where: T is f32, i32, u32 or bool
- vec3(xy: vec2<T>, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3(x: T, yz: vec2<T>) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
- vec3(x: T, y: T, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, i32, u32 or bool
+ vec3(vec3<T>) -> vec3<T> where: T is f32, f16, i32, u32 or bool
+ vec3(T) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3() -> vec3<T> where: T is f32, f16, i32, u32 or bool
+ vec3(xy: vec2<T>, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3(x: T, yz: vec2<T>) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
+ vec3(x: T, y: T, z: T) -> vec3<T> where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool
-4 candidate conversions:
- vec3(vec3<U>) -> vec3<f32> where: T is f32, U is i32, u32 or bool
- vec3(vec3<U>) -> vec3<i32> where: T is i32, U is f32, u32 or bool
- vec3(vec3<U>) -> vec3<u32> where: T is u32, U is f32, i32 or bool
- vec3(vec3<U>) -> vec3<bool> where: T is bool, U is f32, i32 or u32
+5 candidate conversions:
+ vec3(vec3<U>) -> vec3<f32> where: T is f32, U is i32, f16, u32 or bool
+ vec3(vec3<U>) -> vec3<f16> where: T is f16, U is f32, i32, u32 or bool
+ vec3(vec3<U>) -> vec3<i32> where: T is i32, U is f32, f16, u32 or bool
+ vec3(vec3<U>) -> vec3<u32> where: T is u32, U is f32, f16, i32 or bool
+ vec3(vec3<U>) -> vec3<bool> where: T is bool, U is f32, f16, i32 or u32
)");
}
diff --git a/src/tint/resolver/is_host_shareable_test.cc b/src/tint/resolver/is_host_shareable_test.cc
index a167903..0ac3352 100644
--- a/src/tint/resolver/is_host_shareable_test.cc
+++ b/src/tint/resolver/is_host_shareable_test.cc
@@ -35,6 +35,7 @@
EXPECT_TRUE(r()->IsHostShareable(create<sem::I32>()));
EXPECT_TRUE(r()->IsHostShareable(create<sem::U32>()));
EXPECT_TRUE(r()->IsHostShareable(create<sem::F32>()));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::F16>()));
}
TEST_F(ResolverIsHostShareable, NumericVector) {
@@ -47,6 +48,9 @@
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::F32>(), 2u)));
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::F32>(), 3u)));
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::F32>(), 4u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::F16>(), 2u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::F16>(), 3u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::F16>(), 4u)));
}
TEST_F(ResolverIsHostShareable, BoolVector) {
@@ -62,19 +66,32 @@
}
TEST_F(ResolverIsHostShareable, Matrix) {
- auto* vec2 = create<sem::Vector>(create<sem::F32>(), 2u);
- auto* vec3 = create<sem::Vector>(create<sem::F32>(), 3u);
- auto* vec4 = create<sem::Vector>(create<sem::F32>(), 4u);
+ auto* vec2_f32 = create<sem::Vector>(create<sem::F32>(), 2u);
+ auto* vec3_f32 = create<sem::Vector>(create<sem::F32>(), 3u);
+ auto* vec4_f32 = create<sem::Vector>(create<sem::F32>(), 4u);
+ auto* vec2_f16 = create<sem::Vector>(create<sem::F16>(), 2u);
+ auto* vec3_f16 = create<sem::Vector>(create<sem::F16>(), 3u);
+ auto* vec4_f16 = create<sem::Vector>(create<sem::F16>(), 4u);
- EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2, 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2, 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2, 4u)));
- EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3, 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3, 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3, 4u)));
- EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4, 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4, 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4, 4u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2_f32, 2u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2_f32, 3u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2_f32, 4u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3_f32, 2u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3_f32, 3u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3_f32, 4u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4_f32, 2u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4_f32, 3u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4_f32, 4u)));
+
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2_f16, 2u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2_f16, 3u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2_f16, 4u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3_f16, 2u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3_f16, 3u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3_f16, 4u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4_f16, 2u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4_f16, 3u)));
+ EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4_f16, 4u)));
}
TEST_F(ResolverIsHostShareable, Pointer) {
diff --git a/src/tint/resolver/is_storeable_test.cc b/src/tint/resolver/is_storeable_test.cc
index 2d37d8b..80c3e20 100644
--- a/src/tint/resolver/is_storeable_test.cc
+++ b/src/tint/resolver/is_storeable_test.cc
@@ -32,6 +32,7 @@
EXPECT_TRUE(r()->IsStorable(create<sem::I32>()));
EXPECT_TRUE(r()->IsStorable(create<sem::U32>()));
EXPECT_TRUE(r()->IsStorable(create<sem::F32>()));
+ EXPECT_TRUE(r()->IsStorable(create<sem::F16>()));
}
TEST_F(ResolverIsStorableTest, Vector) {
@@ -44,21 +45,36 @@
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F32>(), 2u)));
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F32>(), 3u)));
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F32>(), 4u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F16>(), 2u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F16>(), 3u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F16>(), 4u)));
}
TEST_F(ResolverIsStorableTest, Matrix) {
- auto* vec2 = create<sem::Vector>(create<sem::F32>(), 2u);
- auto* vec3 = create<sem::Vector>(create<sem::F32>(), 3u);
- auto* vec4 = create<sem::Vector>(create<sem::F32>(), 4u);
- EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2, 2u)));
- EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2, 3u)));
- EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2, 4u)));
- EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3, 2u)));
- EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3, 3u)));
- EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3, 4u)));
- EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4, 2u)));
- EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4, 3u)));
- EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4, 4u)));
+ auto* vec2_f32 = create<sem::Vector>(create<sem::F32>(), 2u);
+ auto* vec3_f32 = create<sem::Vector>(create<sem::F32>(), 3u);
+ auto* vec4_f32 = create<sem::Vector>(create<sem::F32>(), 4u);
+ auto* vec2_f16 = create<sem::Vector>(create<sem::F16>(), 2u);
+ auto* vec3_f16 = create<sem::Vector>(create<sem::F16>(), 3u);
+ auto* vec4_f16 = create<sem::Vector>(create<sem::F16>(), 4u);
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2_f32, 2u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2_f32, 3u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2_f32, 4u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3_f32, 2u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3_f32, 3u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3_f32, 4u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4_f32, 2u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4_f32, 3u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4_f32, 4u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2_f16, 2u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2_f16, 3u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2_f16, 4u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3_f16, 2u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3_f16, 3u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3_f16, 4u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4_f16, 2u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4_f16, 3u)));
+ EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4_f16, 4u)));
}
TEST_F(ResolverIsStorableTest, Pointer) {
diff --git a/src/tint/resolver/materialize_test.cc b/src/tint/resolver/materialize_test.cc
index 22d5606..1b935ee 100644
--- a/src/tint/resolver/materialize_test.cc
+++ b/src/tint/resolver/materialize_test.cc
@@ -33,6 +33,7 @@
using i32V = builder::vec<3, i32>;
using u32V = builder::vec<3, u32>;
using f32M = builder::mat<3, 2, f32>;
+using i32Varr = builder::array<3, i32>;
constexpr double kHighestU32 = static_cast<double>(u32::kHighest);
constexpr double kLowestU32 = static_cast<double>(u32::kLowest);
@@ -40,11 +41,16 @@
constexpr double kLowestI32 = static_cast<double>(i32::kLowest);
constexpr double kHighestF32 = static_cast<double>(f32::kHighest);
constexpr double kLowestF32 = static_cast<double>(f32::kLowest);
+// constexpr double kHighestF16 = static_cast<double>(f16::kHighest);
+// constexpr double kLowestF16 = static_cast<double>(f16::kLowest);
constexpr double kTooBigF32 = static_cast<double>(3.5e+38);
+// constexpr double kTooBigF16 = static_cast<double>(6.6e+4);
constexpr double kPiF64 = 3.141592653589793;
constexpr double kPiF32 = 3.1415927410125732; // kPiF64 quantized to f32
+// constexpr double kPiF16 = 3.140625; // kPiF64 quantized to f16
constexpr double kSubnormalF32 = 0x1.0p-128;
+// constexpr double kSubnormalF16 = 0x1.0p-16;
enum class Expectation {
kMaterialize,
@@ -67,12 +73,61 @@
return o << "<unknown>";
}
+template <typename CASE>
+class MaterializeTest : public resolver::ResolverTestWithParam<CASE> {
+ protected:
+ using ProgramBuilder::FriendlyName;
+
+ void CheckTypesAndValues(const sem::Expression* expr,
+ const tint::sem::Type* expected_sem_ty,
+ const std::variant<AInt, AFloat>& expected_value) {
+ std::visit([&](auto v) { CheckTypesAndValuesImpl(expr, expected_sem_ty, v); },
+ expected_value);
+ }
+
+ private:
+ template <typename T>
+ void CheckTypesAndValuesImpl(const sem::Expression* expr,
+ const tint::sem::Type* expected_sem_ty,
+ T expected_value) {
+ EXPECT_TYPE(expr->Type(), expected_sem_ty);
+
+ auto* value = expr->ConstantValue();
+ ASSERT_NE(value, nullptr);
+ EXPECT_TYPE(expr->Type(), value->Type());
+
+ tint::Switch(
+ expected_sem_ty, //
+ [&](const sem::Vector* v) {
+ for (uint32_t i = 0; i < v->Width(); i++) {
+ auto* el = value->Index(i);
+ ASSERT_NE(el, nullptr);
+ EXPECT_TYPE(el->Type(), v->type());
+ EXPECT_EQ(std::get<T>(el->Value()), expected_value);
+ }
+ },
+ [&](const sem::Matrix* m) {
+ for (uint32_t c = 0; c < m->columns(); c++) {
+ auto* column = value->Index(c);
+ ASSERT_NE(column, nullptr);
+ EXPECT_TYPE(column->Type(), m->ColumnType());
+ for (uint32_t r = 0; r < m->rows(); r++) {
+ auto* el = column->Index(r);
+ ASSERT_NE(el, nullptr);
+ EXPECT_TYPE(el->Type(), m->type());
+ EXPECT_EQ(std::get<T>(el->Value()), expected_value);
+ }
+ }
+ },
+ [&](Default) { EXPECT_EQ(std::get<T>(value->Value()), expected_value); });
+ }
+};
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// MaterializeAbstractNumericToConcreteType
// Tests that an abstract-numeric will materialize to the expected concrete type
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace materialize_abstract_numeric_to_concrete_type {
-
// How should the materialization occur?
enum class Method {
// var a : target_type = abstract_expr;
@@ -241,10 +296,10 @@
}
using MaterializeAbstractNumericToConcreteType =
- resolver::ResolverTestWithParam<std::tuple<Expectation, Method, Data>>;
+ MaterializeTest<std::tuple<Expectation, Method, Data>>;
TEST_P(MaterializeAbstractNumericToConcreteType, Test) {
- // Once F16 is properly supported, we'll need to enable this:
+ // Once built-in and ops using f16 is properly supported, we'll need to enable this:
// Enable(ast::Extension::kF16);
const auto& param = GetParam();
@@ -317,30 +372,12 @@
break;
}
- auto check_types_and_values = [&](const sem::Expression* expr) {
- auto* target_sem_ty = data.target_sem_ty(*this);
-
- EXPECT_TYPE(expr->Type(), target_sem_ty);
- EXPECT_TYPE(expr->ConstantValue().Type(), target_sem_ty);
-
- uint32_t num_elems = 0;
- const sem::Type* target_sem_el_ty = sem::Type::ElementOf(target_sem_ty, &num_elems);
- EXPECT_TYPE(expr->ConstantValue().ElementType(), target_sem_el_ty);
- expr->ConstantValue().WithElements([&](auto&& vec) {
- using VEC_TY = std::decay_t<decltype(vec)>;
- using EL_TY = typename VEC_TY::value_type;
- ASSERT_TRUE(std::holds_alternative<EL_TY>(data.materialized_value));
- VEC_TY expected(num_elems, std::get<EL_TY>(data.materialized_value));
- EXPECT_EQ(vec, expected);
- });
- };
-
switch (expectation) {
case Expectation::kMaterialize: {
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* materialize = Sem().Get<sem::Materialize>(abstract_expr);
ASSERT_NE(materialize, nullptr);
- check_types_and_values(materialize);
+ CheckTypesAndValues(materialize, data.target_sem_ty(*this), data.materialized_value);
break;
}
case Expectation::kNoMaterialize: {
@@ -348,7 +385,7 @@
auto* sem = Sem().Get(abstract_expr);
ASSERT_NE(sem, nullptr);
EXPECT_FALSE(sem->Is<sem::Materialize>());
- check_types_and_values(sem);
+ CheckTypesAndValues(sem, data.target_sem_ty(*this), data.materialized_value);
break;
}
case Expectation::kInvalidConversion: {
@@ -408,8 +445,8 @@
/// Methods that do not materialize
constexpr Method kNoMaterializeMethods[] = {
Method::kPhonyAssign,
- // TODO(crbug.com/tint/1504): Enable once we have abstract overloads of builtins / binary ops:
- // Method::kBuiltinArg, Method::kBinaryOp,
+ // TODO(crbug.com/tint/1504): Enable once we have abstract overloads of builtins / binary
+ // ops: Method::kBuiltinArg, Method::kBinaryOp,
};
INSTANTIATE_TEST_SUITE_P(
MaterializeScalar,
@@ -417,23 +454,28 @@
testing::Combine(testing::Values(Expectation::kMaterialize),
testing::ValuesIn(kScalarMethods),
testing::ValuesIn(std::vector<Data>{
- Types<i32, AInt>(0_a, 0.0), //
- Types<i32, AInt>(1_a, 1.0), //
- Types<i32, AInt>(-1_a, -1.0), //
- Types<i32, AInt>(AInt(kHighestI32), kHighestI32), //
- Types<i32, AInt>(AInt(kLowestI32), kLowestI32), //
- Types<u32, AInt>(0_a, 0.0), //
- Types<u32, AInt>(1_a, 1.0), //
- Types<u32, AInt>(AInt(kHighestU32), kHighestU32), //
- Types<u32, AInt>(AInt(kLowestU32), kLowestU32), //
- Types<f32, AFloat>(0.0_a, 0.0), //
- Types<f32, AFloat>(AFloat(kHighestF32), kHighestF32), //
- Types<f32, AFloat>(AFloat(kLowestF32), kLowestF32), //
- Types<f32, AFloat>(AFloat(kPiF32), kPiF64), //
- Types<f32, AFloat>(AFloat(kSubnormalF32), kSubnormalF32), //
- Types<f32, AFloat>(AFloat(-kSubnormalF32), -kSubnormalF32), //
- /* Types<f16, AFloat>(1.0_a), */ //
- /* Types<f16, AFloat>(1.0_a), */ //
+ Types<i32, AInt>(0_a, 0.0), //
+ Types<i32, AInt>(1_a, 1.0), //
+ Types<i32, AInt>(-1_a, -1.0), //
+ Types<i32, AInt>(AInt(kHighestI32), kHighestI32), //
+ Types<i32, AInt>(AInt(kLowestI32), kLowestI32), //
+ Types<u32, AInt>(0_a, 0.0), //
+ Types<u32, AInt>(1_a, 1.0), //
+ Types<u32, AInt>(AInt(kHighestU32), kHighestU32), //
+ Types<u32, AInt>(AInt(kLowestU32), kLowestU32), //
+ Types<f32, AFloat>(0.0_a, 0.0), //
+ Types<f32, AFloat>(AFloat(kHighestF32), kHighestF32), //
+ Types<f32, AFloat>(AFloat(kLowestF32), kLowestF32), //
+ Types<f32, AFloat>(AFloat(kPiF32), kPiF64), //
+ Types<f32, AFloat>(AFloat(kSubnormalF32), kSubnormalF32), //
+ Types<f32, AFloat>(AFloat(-kSubnormalF32), -kSubnormalF32), //
+ /* Types<f16, AFloat>(0.0_a, 0.0), */ //
+ /* Types<f16, AFloat>(1.0_a, 1.0), */ //
+ /* Types<f16, AFloat>(AFloat(kHighestF16), kHighestF16), */ //
+ /* Types<f16, AFloat>(AFloat(kLowestF16), kLowestF16), */ //
+ /* Types<f16, AFloat>(AFloat(kPiF16), kPiF64), */ //
+ /* Types<f16, AFloat>(AFloat(kSubnormalF16), kSubnormalF16), */ //
+ /* Types<f16, AFloat>(AFloat(-kSubnormalF16), -kSubnormalF16), */ //
})));
INSTANTIATE_TEST_SUITE_P(
@@ -442,25 +484,31 @@
testing::Combine(testing::Values(Expectation::kMaterialize),
testing::ValuesIn(kVectorMethods),
testing::ValuesIn(std::vector<Data>{
- Types<i32V, AIntV>(0_a, 0.0), //
- Types<i32V, AIntV>(1_a, 1.0), //
- Types<i32V, AIntV>(-1_a, -1.0), //
- Types<i32V, AIntV>(AInt(kHighestI32), kHighestI32), //
- Types<i32V, AIntV>(AInt(kLowestI32), kLowestI32), //
- Types<u32V, AIntV>(0_a, 0.0), //
- Types<u32V, AIntV>(1_a, 1.0), //
- Types<u32V, AIntV>(AInt(kHighestU32), kHighestU32), //
- Types<u32V, AIntV>(AInt(kLowestU32), kLowestU32), //
- Types<f32V, AFloatV>(0.0_a, 0.0), //
- Types<f32V, AFloatV>(1.0_a, 1.0), //
- Types<f32V, AFloatV>(-1.0_a, -1.0), //
- Types<f32V, AFloatV>(AFloat(kHighestF32), kHighestF32), //
- Types<f32V, AFloatV>(AFloat(kLowestF32), kLowestF32), //
- Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64), //
- Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32), //
- Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32), //
- /* Types<f16V, AFloatV>(1.0_a), */ //
- /* Types<f16V, AFloatV>(1.0_a), */ //
+ Types<i32V, AIntV>(0_a, 0.0), //
+ Types<i32V, AIntV>(1_a, 1.0), //
+ Types<i32V, AIntV>(-1_a, -1.0), //
+ Types<i32V, AIntV>(AInt(kHighestI32), kHighestI32), //
+ Types<i32V, AIntV>(AInt(kLowestI32), kLowestI32), //
+ Types<u32V, AIntV>(0_a, 0.0), //
+ Types<u32V, AIntV>(1_a, 1.0), //
+ Types<u32V, AIntV>(AInt(kHighestU32), kHighestU32), //
+ Types<u32V, AIntV>(AInt(kLowestU32), kLowestU32), //
+ Types<f32V, AFloatV>(0.0_a, 0.0), //
+ Types<f32V, AFloatV>(1.0_a, 1.0), //
+ Types<f32V, AFloatV>(-1.0_a, -1.0), //
+ Types<f32V, AFloatV>(AFloat(kHighestF32), kHighestF32), //
+ Types<f32V, AFloatV>(AFloat(kLowestF32), kLowestF32), //
+ Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64), //
+ Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32), //
+ Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32), //
+ /* Types<f16V, AFloatV>(0.0_a, 0.0), */ //
+ /* Types<f16V, AFloatV>(1.0_a, 1.0), */ //
+ /* Types<f16V, AFloatV>(-1.0_a, -1.0), */ //
+ /* Types<f16V, AFloatV>(AFloat(kHighestF16), kHighestF16), */ //
+ /* Types<f16V, AFloatV>(AFloat(kLowestF16), kLowestF16), */ //
+ /* Types<f16V, AFloatV>(AFloat(kPiF16), kPiF64), */ //
+ /* Types<f16V, AFloatV>(AFloat(kSubnormalF16), kSubnormalF16), */ //
+ /* Types<f16V, AFloatV>(AFloat(-kSubnormalF16), -kSubnormalF16), */ //
})));
INSTANTIATE_TEST_SUITE_P(
@@ -469,15 +517,22 @@
testing::Combine(testing::Values(Expectation::kMaterialize),
testing::ValuesIn(kMatrixMethods),
testing::ValuesIn(std::vector<Data>{
- Types<f32M, AFloatM>(0.0_a, 0.0), //
- Types<f32M, AFloatM>(1.0_a, 1.0), //
- Types<f32M, AFloatM>(-1.0_a, -1.0), //
- Types<f32M, AFloatM>(AFloat(kHighestF32), kHighestF32), //
- Types<f32M, AFloatM>(AFloat(kLowestF32), kLowestF32), //
- Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64), //
- Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32), //
- Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32), //
- /* Types<f16V, AFloatM>(1.0_a), */ //
+ Types<f32M, AFloatM>(0.0_a, 0.0), //
+ Types<f32M, AFloatM>(1.0_a, 1.0), //
+ Types<f32M, AFloatM>(-1.0_a, -1.0), //
+ Types<f32M, AFloatM>(AFloat(kHighestF32), kHighestF32), //
+ Types<f32M, AFloatM>(AFloat(kLowestF32), kLowestF32), //
+ Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64), //
+ Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32), //
+ Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32), //
+ /* Types<f16M, AFloatM>(0.0_a, 0.0), */ //
+ /* Types<f16M, AFloatM>(1.0_a, 1.0), */ //
+ /* Types<f16M, AFloatM>(-1.0_a, -1.0), */ //
+ /* Types<f16M, AFloatM>(AFloat(kHighestF16), kHighestF16), */ //
+ /* Types<f16M, AFloatM>(AFloat(kLowestF16), kLowestF16), */ //
+ /* Types<f16M, AFloatM>(AFloat(kPiF16), kPiF64), */ //
+ /* Types<f16M, AFloatM>(AFloat(kSubnormalF16), kSubnormalF16), */ //
+ /* Types<f16M, AFloatM>(AFloat(-kSubnormalF16), -kSubnormalF16), */ //
})));
INSTANTIATE_TEST_SUITE_P(MaterializeSwitch,
@@ -526,10 +581,14 @@
testing::Combine(testing::Values(Expectation::kInvalidConversion),
testing::ValuesIn(kScalarMethods),
testing::ValuesIn(std::vector<Data>{
- Types<i32, AFloat>(), //
- Types<u32, AFloat>(), //
- Types<i32V, AFloatV>(), //
- Types<u32V, AFloatV>(), //
+ Types<i32, AFloat>(), //
+ Types<u32, AFloat>(), //
+ Types<i32V, AFloatV>(), //
+ Types<u32V, AFloatV>(), //
+ Types<i32Varr, AInt>(), //
+ Types<i32Varr, AIntV>(), //
+ Types<i32Varr, AFloat>(), //
+ Types<i32Varr, AFloatV>(), //
})));
INSTANTIATE_TEST_SUITE_P(ScalarValueCannotBeRepresented,
@@ -537,14 +596,14 @@
testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
testing::ValuesIn(kScalarMethods),
testing::ValuesIn(std::vector<Data>{
- Types<i32, AInt>(0_a, kHighestI32 + 1), //
- Types<i32, AInt>(0_a, kLowestI32 - 1), //
- Types<u32, AInt>(0_a, kHighestU32 + 1), //
- Types<u32, AInt>(0_a, kLowestU32 - 1), //
- Types<f32, AFloat>(0.0_a, kTooBigF32), //
- Types<f32, AFloat>(0.0_a, -kTooBigF32), //
- /* Types<f16, AFloat>(), */ //
- /* Types<f16, AFloat>(), */ //
+ Types<i32, AInt>(0_a, kHighestI32 + 1), //
+ Types<i32, AInt>(0_a, kLowestI32 - 1), //
+ Types<u32, AInt>(0_a, kHighestU32 + 1), //
+ Types<u32, AInt>(0_a, kLowestU32 - 1), //
+ Types<f32, AFloat>(0.0_a, kTooBigF32), //
+ Types<f32, AFloat>(0.0_a, -kTooBigF32), //
+ /* Types<f16, AFloat>(0.0_a, kTooBigF16), */ //
+ /* Types<f16, AFloat>(0.0_a, -kTooBigF16), */ //
})));
INSTANTIATE_TEST_SUITE_P(VectorValueCannotBeRepresented,
@@ -552,14 +611,14 @@
testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
testing::ValuesIn(kVectorMethods),
testing::ValuesIn(std::vector<Data>{
- Types<i32V, AIntV>(0_a, kHighestI32 + 1), //
- Types<i32V, AIntV>(0_a, kLowestI32 - 1), //
- Types<u32V, AIntV>(0_a, kHighestU32 + 1), //
- Types<u32V, AIntV>(0_a, kLowestU32 - 1), //
- Types<f32V, AFloatV>(0.0_a, kTooBigF32), //
- Types<f32V, AFloatV>(0.0_a, -kTooBigF32), //
- /* Types<f16V, AFloatV>(), */ //
- /* Types<f16V, AFloatV>(), */ //
+ Types<i32V, AIntV>(0_a, kHighestI32 + 1), //
+ Types<i32V, AIntV>(0_a, kLowestI32 - 1), //
+ Types<u32V, AIntV>(0_a, kHighestU32 + 1), //
+ Types<u32V, AIntV>(0_a, kLowestU32 - 1), //
+ Types<f32V, AFloatV>(0.0_a, kTooBigF32), //
+ Types<f32V, AFloatV>(0.0_a, -kTooBigF32), //
+ /* Types<f16V, AFloatV>(0.0_a, kTooBigF16), */ //
+ /* Types<f16V, AFloatV>(0.0_a, -kTooBigF16), */ //
})));
INSTANTIATE_TEST_SUITE_P(MatrixValueCannotBeRepresented,
@@ -567,10 +626,10 @@
testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
testing::ValuesIn(kMatrixMethods),
testing::ValuesIn(std::vector<Data>{
- Types<f32M, AFloatM>(0.0_a, kTooBigF32), //
- Types<f32M, AFloatM>(0.0_a, -kTooBigF32), //
- /* Types<f16M, AFloatM>(), */ //
- /* Types<f16M, AFloatM>(), */ //
+ Types<f32M, AFloatM>(0.0_a, kTooBigF32), //
+ Types<f32M, AFloatM>(0.0_a, -kTooBigF32), //
+ /* Types<f16M, AFloatM>(0.0_a, kTooBigF16), */ //
+ /* Types<f16M, AFloatM>(0.0_a, -kTooBigF16), */ //
})));
} // namespace materialize_abstract_numeric_to_concrete_type
@@ -675,12 +734,9 @@
}
using MaterializeAbstractNumericToDefaultType =
- resolver::ResolverTestWithParam<std::tuple<Expectation, Method, Data>>;
+ MaterializeTest<std::tuple<Expectation, Method, Data>>;
TEST_P(MaterializeAbstractNumericToDefaultType, Test) {
- // Once F16 is properly supported, we'll need to enable this:
- // Enable(ast::Extension::kF16);
-
const auto& param = GetParam();
const auto& expectation = std::get<0>(param);
const auto& method = std::get<1>(param);
@@ -721,36 +777,19 @@
{WorkgroupSize(abstract_expr()), Stage(ast::PipelineStage::kCompute)});
break;
case Method::kIndex:
- Global("arr", ty.array<i32, 4>(), ast::StorageClass::kPrivate);
+ GlobalVar("arr", ty.array<i32, 4>(), ast::StorageClass::kPrivate);
WrapInFunction(IndexAccessor("arr", abstract_expr()));
break;
}
- auto check_types_and_values = [&](const sem::Expression* expr) {
- auto* expected_sem_ty = data.expected_sem_ty(*this);
-
- EXPECT_TYPE(expr->Type(), expected_sem_ty);
- EXPECT_TYPE(expr->ConstantValue().Type(), expected_sem_ty);
-
- uint32_t num_elems = 0;
- const sem::Type* expected_sem_el_ty = sem::Type::ElementOf(expected_sem_ty, &num_elems);
- EXPECT_TYPE(expr->ConstantValue().ElementType(), expected_sem_el_ty);
- expr->ConstantValue().WithElements([&](auto&& vec) {
- using VEC_TY = std::decay_t<decltype(vec)>;
- using EL_TY = typename VEC_TY::value_type;
- ASSERT_TRUE(std::holds_alternative<EL_TY>(data.materialized_value));
- VEC_TY expected(num_elems, std::get<EL_TY>(data.materialized_value));
- EXPECT_EQ(vec, expected);
- });
- };
-
switch (expectation) {
case Expectation::kMaterialize: {
ASSERT_TRUE(r()->Resolve()) << r()->error();
for (auto* expr : abstract_exprs) {
auto* materialize = Sem().Get<sem::Materialize>(expr);
ASSERT_NE(materialize, nullptr);
- check_types_and_values(materialize);
+ CheckTypesAndValues(materialize, data.expected_sem_ty(*this),
+ data.materialized_value);
}
break;
}
@@ -959,5 +998,25 @@
} // namespace materialize_abstract_numeric_to_default_type
+using MaterializeAbstractNumericToUnrelatedType = resolver::ResolverTest;
+
+TEST_F(MaterializeAbstractNumericToUnrelatedType, AIntToStructVarCtor) {
+ Structure("S", {Member("a", ty.i32())});
+ WrapInFunction(Decl(Var("v", ty.type_name("S"), Expr(Source{{12, 34}}, 1_a))));
+ ASSERT_FALSE(r()->Resolve());
+ EXPECT_THAT(
+ r()->error(),
+ testing::HasSubstr("error: cannot convert value of type 'abstract-int' to type 'S'"));
+}
+
+TEST_F(MaterializeAbstractNumericToUnrelatedType, AIntToStructLetCtor) {
+ Structure("S", {Member("a", ty.i32())});
+ WrapInFunction(Decl(Let("v", ty.type_name("S"), Expr(Source{{12, 34}}, 1_a))));
+ ASSERT_FALSE(r()->Resolve());
+ EXPECT_THAT(
+ r()->error(),
+ testing::HasSubstr("error: cannot convert value of type 'abstract-int' to type 'S'"));
+}
+
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/resolver/ptr_ref_test.cc b/src/tint/resolver/ptr_ref_test.cc
index 69b7e54..037c6ff 100644
--- a/src/tint/resolver/ptr_ref_test.cc
+++ b/src/tint/resolver/ptr_ref_test.cc
@@ -59,18 +59,18 @@
auto* buf = Structure("S", {Member("m", ty.i32())});
auto* function = Var("f", ty.i32());
- auto* private_ = Global("p", ty.i32(), ast::StorageClass::kPrivate);
- auto* workgroup = Global("w", ty.i32(), ast::StorageClass::kWorkgroup);
- auto* uniform = Global("ub", ty.Of(buf), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
- auto* storage = Global("sb", ty.Of(buf), ast::StorageClass::kStorage,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(0),
- });
+ auto* private_ = GlobalVar("p", ty.i32(), ast::StorageClass::kPrivate);
+ auto* workgroup = GlobalVar("w", ty.i32(), ast::StorageClass::kWorkgroup);
+ auto* uniform = GlobalVar("ub", ty.Of(buf), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
+ auto* storage = GlobalVar("sb", ty.Of(buf), ast::StorageClass::kStorage,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(0u),
+ });
auto* function_ptr =
Let("f_ptr", ty.pointer(ty.i32(), ast::StorageClass::kFunction), AddressOf(function));
diff --git a/src/tint/resolver/ptr_ref_validation_test.cc b/src/tint/resolver/ptr_ref_validation_test.cc
index b011dd0..768783b 100644
--- a/src/tint/resolver/ptr_ref_validation_test.cc
+++ b/src/tint/resolver/ptr_ref_validation_test.cc
@@ -54,7 +54,8 @@
TEST_F(ResolverPtrRefValidationTest, AddressOfHandle) {
// @group(0) @binding(0) var t: texture_3d<f32>;
// &t
- Global("t", ty.sampled_texture(ast::TextureDimension::k3d, ty.f32()), GroupAndBinding(0u, 0u));
+ GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k3d, ty.f32()),
+ GroupAndBinding(0u, 0u));
auto* expr = AddressOf(Expr(Source{{12, 34}}, "t"));
WrapInFunction(expr);
@@ -93,7 +94,8 @@
TEST_F(ResolverPtrRefValidationTest, IndirectOfAddressOfHandle) {
// @group(0) @binding(0) var t: texture_3d<f32>;
// *&t
- Global("t", ty.sampled_texture(ast::TextureDimension::k3d, ty.f32()), GroupAndBinding(0u, 0u));
+ GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k3d, ty.f32()),
+ GroupAndBinding(0u, 0u));
auto* expr = Deref(AddressOf(Expr(Source{{12, 34}}, "t")));
WrapInFunction(expr);
@@ -141,11 +143,11 @@
// }
auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
- auto* storage = Global("s", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* storage = GlobalVar("s", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 2_i);
auto* ptr =
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index be1765c..9ef9a30 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -62,6 +62,7 @@
#include "src/tint/sem/for_loop_statement.h"
#include "src/tint/sem/function.h"
#include "src/tint/sem/if_statement.h"
+#include "src/tint/sem/index_accessor_expression.h"
#include "src/tint/sem/loop_statement.h"
#include "src/tint/sem/materialize.h"
#include "src/tint/sem/member_accessor_expression.h"
@@ -312,57 +313,214 @@
}
sem::Variable* Resolver::Variable(const ast::Variable* v, bool is_global) {
+ return Switch(
+ v, //
+ [&](const ast::Var* var) { return Var(var, is_global); },
+ [&](const ast::Let* let) { return Let(let, is_global); },
+ [&](const ast::Override* override) { return Override(override); },
+ [&](const ast::Const* const_) { return Const(const_, is_global); },
+ [&](Default) {
+ TINT_ICE(Resolver, diagnostics_)
+ << "Resolver::GlobalVariable() called with a unknown variable type: "
+ << v->TypeInfo().name;
+ return nullptr;
+ });
+}
+
+sem::Variable* Resolver::Let(const ast::Let* v, bool is_global) {
+ const sem::Type* ty = nullptr;
+
+ // If the variable has a declared type, resolve it.
+ if (v->type) {
+ ty = Type(v->type);
+ if (!ty) {
+ return nullptr;
+ }
+ }
+
+ if (!v->constructor) {
+ AddError("'let' declaration must have an initializer", v->source);
+ return nullptr;
+ }
+
+ auto* rhs = Materialize(Expression(v->constructor), ty);
+ if (!rhs) {
+ return nullptr;
+ }
+
+ // If the variable has no declared type, infer it from the RHS
+ if (!ty) {
+ ty = rhs->Type()->UnwrapRef(); // Implicit load of RHS
+ }
+
+ if (rhs && !validator_.VariableInitializer(v, ast::StorageClass::kNone, ty, rhs)) {
+ return nullptr;
+ }
+
+ if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, const_cast<sem::Type*>(ty),
+ v->source)) {
+ AddNote("while instantiating 'let' " + builder_->Symbols().NameFor(v->symbol), v->source);
+ return nullptr;
+ }
+
+ sem::Variable* sem = nullptr;
+ if (is_global) {
+ sem = builder_->create<sem::GlobalVariable>(
+ v, ty, ast::StorageClass::kNone, ast::Access::kUndefined, /* constant_value */ nullptr,
+ sem::BindingPoint{});
+ } else {
+ sem = builder_->create<sem::LocalVariable>(v, ty, ast::StorageClass::kNone,
+ ast::Access::kUndefined, current_statement_,
+ /* constant_value */ nullptr);
+ }
+
+ sem->SetConstructor(rhs);
+ builder_->Sem().Add(v, sem);
+ return sem;
+}
+
+sem::Variable* Resolver::Override(const ast::Override* v) {
+ const sem::Type* ty = nullptr;
+
+ // If the variable has a declared type, resolve it.
+ if (v->type) {
+ ty = Type(v->type);
+ if (!ty) {
+ return nullptr;
+ }
+ }
+
+ const sem::Expression* rhs = nullptr;
+
+ // Does the variable have a constructor?
+ if (v->constructor) {
+ rhs = Materialize(Expression(v->constructor), ty);
+ if (!rhs) {
+ return nullptr;
+ }
+
+ // If the variable has no declared type, infer it from the RHS
+ if (!ty) {
+ ty = rhs->Type()->UnwrapRef(); // Implicit load of RHS
+ }
+ } else if (!ty) {
+ AddError("override declaration requires a type or initializer", v->source);
+ return nullptr;
+ }
+
+ if (rhs && !validator_.VariableInitializer(v, ast::StorageClass::kNone, ty, rhs)) {
+ return nullptr;
+ }
+
+ if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, const_cast<sem::Type*>(ty),
+ v->source)) {
+ AddNote("while instantiating 'override' " + builder_->Symbols().NameFor(v->symbol),
+ v->source);
+ return nullptr;
+ }
+
+ auto* sem = builder_->create<sem::GlobalVariable>(
+ v, ty, ast::StorageClass::kNone, ast::Access::kUndefined, /* constant_value */ nullptr,
+ sem::BindingPoint{});
+
+ if (auto* id = ast::GetAttribute<ast::IdAttribute>(v->attributes)) {
+ sem->SetConstantId(static_cast<uint16_t>(id->value));
+ }
+
+ sem->SetConstructor(rhs);
+ builder_->Sem().Add(v, sem);
+ return sem;
+}
+
+sem::Variable* Resolver::Const(const ast::Const* c, bool is_global) {
+ const sem::Type* ty = nullptr;
+
+ // If the variable has a declared type, resolve it.
+ if (c->type) {
+ ty = Type(c->type);
+ if (!ty) {
+ return nullptr;
+ }
+ }
+
+ if (!c->constructor) {
+ AddError("'const' declaration must have an initializer", c->source);
+ return nullptr;
+ }
+
+ const auto* rhs = Expression(c->constructor);
+ if (!rhs) {
+ return nullptr;
+ }
+
+ if (ty) {
+ // If an explicit type was specified, materialize to that type
+ rhs = Materialize(rhs, ty);
+ } else {
+ // If no type was specified, infer it from the RHS
+ ty = rhs->Type();
+ }
+
+ const auto value = rhs->ConstantValue();
+ if (!value) {
+ AddError("'const' initializer must be constant expression", c->constructor->source);
+ return nullptr;
+ }
+
+ if (!validator_.VariableInitializer(c, ast::StorageClass::kNone, ty, rhs)) {
+ return nullptr;
+ }
+
+ if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, const_cast<sem::Type*>(ty),
+ c->source)) {
+ AddNote("while instantiating 'const' " + builder_->Symbols().NameFor(c->symbol), c->source);
+ return nullptr;
+ }
+
+ auto* sem = is_global ? static_cast<sem::Variable*>(builder_->create<sem::GlobalVariable>(
+ c, ty, ast::StorageClass::kNone, ast::Access::kUndefined, value,
+ sem::BindingPoint{}))
+ : static_cast<sem::Variable*>(builder_->create<sem::LocalVariable>(
+ c, ty, ast::StorageClass::kNone, ast::Access::kUndefined,
+ current_statement_, value));
+
+ sem->SetConstructor(rhs);
+ builder_->Sem().Add(c, sem);
+ return sem;
+}
+
+sem::Variable* Resolver::Var(const ast::Var* var, bool is_global) {
const sem::Type* storage_ty = nullptr;
// If the variable has a declared type, resolve it.
- if (auto* ty = v->type) {
+ if (auto* ty = var->type) {
storage_ty = Type(ty);
if (!storage_ty) {
return nullptr;
}
}
- auto* as_var = v->As<ast::Var>();
- auto* as_let = v->As<ast::Let>();
- auto* as_override = v->As<ast::Override>();
-
const sem::Expression* rhs = nullptr;
// Does the variable have a constructor?
- if (v->constructor) {
- rhs = Materialize(Expression(v->constructor), storage_ty);
+ if (var->constructor) {
+ rhs = Materialize(Expression(var->constructor), storage_ty);
if (!rhs) {
return nullptr;
}
-
// If the variable has no declared type, infer it from the RHS
if (!storage_ty) {
- if (as_var && is_global) {
- AddError("module-scope 'var' declaration must specify a type", v->source);
- return nullptr;
- }
-
storage_ty = rhs->Type()->UnwrapRef(); // Implicit load of RHS
}
- } else if (as_let) {
- AddError("'let' declaration must have an initializer", v->source);
- return nullptr;
- } else if (!v->type) {
- AddError((is_global) ? "module-scope 'var' declaration requires a type or initializer"
- : "function-scope 'var' declaration requires a type or initializer",
- v->source);
- return nullptr;
}
if (!storage_ty) {
- TINT_ICE(Resolver, diagnostics_) << "failed to determine storage type for variable '" +
- builder_->Symbols().NameFor(v->symbol) + "'\n"
- << "Source: " << v->source;
+ AddError("var declaration requires a type or initializer", var->source);
return nullptr;
}
- auto storage_class = as_var ? as_var->declared_storage_class : ast::StorageClass::kNone;
- if (storage_class == ast::StorageClass::kNone && as_var) {
+ auto storage_class = var->declared_storage_class;
+ if (storage_class == ast::StorageClass::kNone) {
// No declared storage class. Infer from usage / type.
if (!is_global) {
storage_class = ast::StorageClass::kFunction;
@@ -375,65 +533,47 @@
}
}
- if (!is_global && as_var && storage_class != ast::StorageClass::kFunction &&
- validator_.IsValidationEnabled(v->attributes,
+ if (!is_global && storage_class != ast::StorageClass::kFunction &&
+ validator_.IsValidationEnabled(var->attributes,
ast::DisabledValidation::kIgnoreStorageClass)) {
- AddError("function-scope 'var' declaration must use 'function' storage class", v->source);
+ AddError("function-scope 'var' declaration must use 'function' storage class", var->source);
return nullptr;
}
- auto access = as_var ? as_var->declared_access : ast::Access::kUndefined;
+ auto access = var->declared_access;
if (access == ast::Access::kUndefined) {
access = DefaultAccessForStorageClass(storage_class);
}
- auto* var_ty = storage_ty;
- if (as_var) {
- // Variable declaration. Unlike `let` and parameters, `var` has storage.
- // Variables are always of a reference type to the declared storage type.
- var_ty = builder_->create<sem::Reference>(storage_ty, storage_class, access);
- }
-
- if (rhs && !validator_.VariableConstructorOrCast(v, storage_class, storage_ty, rhs->Type())) {
+ if (rhs && !validator_.VariableInitializer(var, storage_class, storage_ty, rhs)) {
return nullptr;
}
- if (!ApplyStorageClassUsageToType(storage_class, const_cast<sem::Type*>(var_ty), v->source)) {
- AddNote("while instantiating variable " + builder_->Symbols().NameFor(v->symbol),
- v->source);
+ auto* var_ty = builder_->create<sem::Reference>(storage_ty, storage_class, access);
+
+ if (!ApplyStorageClassUsageToType(storage_class, var_ty, var->source)) {
+ AddNote("while instantiating 'var' " + builder_->Symbols().NameFor(var->symbol),
+ var->source);
return nullptr;
}
+ sem::Variable* sem = nullptr;
if (is_global) {
sem::BindingPoint binding_point;
- if (as_var) {
- if (auto bp = as_var->BindingPoint()) {
- binding_point = {bp.group->value, bp.binding->value};
- }
+ if (auto bp = var->BindingPoint()) {
+ binding_point = {bp.group->value, bp.binding->value};
}
+ sem = builder_->create<sem::GlobalVariable>(var, var_ty, storage_class, access,
+ /* constant_value */ nullptr, binding_point);
- bool has_const_val = rhs && as_let && !as_override;
- auto* global = builder_->create<sem::GlobalVariable>(
- v, var_ty, storage_class, access,
- has_const_val ? rhs->ConstantValue() : sem::Constant{}, binding_point);
-
- if (as_override) {
- if (auto* id = ast::GetAttribute<ast::IdAttribute>(v->attributes)) {
- global->SetConstantId(static_cast<uint16_t>(id->value));
- }
- }
-
- global->SetConstructor(rhs);
- builder_->Sem().Add(v, global);
- return global;
+ } else {
+ sem = builder_->create<sem::LocalVariable>(
+ var, var_ty, storage_class, access, current_statement_, /* constant_value */ nullptr);
}
- auto* local = builder_->create<sem::LocalVariable>(
- v, var_ty, storage_class, access, current_statement_,
- (rhs && as_let) ? rhs->ConstantValue() : sem::Constant{});
- builder_->Sem().Add(v, local);
- local->SetConstructor(rhs);
- return local;
+ sem->SetConstructor(rhs);
+ builder_->Sem().Add(var, sem);
+ return sem;
}
sem::Parameter* Resolver::Parameter(const ast::Parameter* param, uint32_t index) {
@@ -539,14 +679,6 @@
return nullptr;
}
- const bool is_var = v->Is<ast::Var>();
-
- auto storage_class = sem->StorageClass();
- if (is_var && storage_class == ast::StorageClass::kNone) {
- AddError("module-scope 'var' declaration must have a storage class", v->source);
- return nullptr;
- }
-
for (auto* attr : v->attributes) {
Mark(attr);
@@ -570,7 +702,7 @@
return nullptr;
}
- return sem->As<sem::GlobalVariable>();
+ return sem;
}
sem::Function* Resolver::Function(const ast::Function* decl) {
@@ -725,7 +857,7 @@
bool Resolver::WorkgroupSize(const ast::Function* func) {
// Set work-group size defaults.
sem::WorkgroupSize ws;
- for (int i = 0; i < 3; i++) {
+ for (size_t i = 0; i < 3; i++) {
ws[i].value = 1;
ws[i].overridable_const = nullptr;
}
@@ -740,11 +872,11 @@
std::array<const sem::Type*, 3> arg_tys = {};
size_t arg_count = 0;
- constexpr const char* kErrBadType =
- "workgroup_size argument must be either literal or module-scope constant of type i32 "
- "or u32";
+ constexpr const char* kErrBadExpr =
+ "workgroup_size argument must be either a literal, constant, or overridable of type "
+ "abstract-integer, i32 or u32";
- for (int i = 0; i < 3; i++) {
+ for (size_t i = 0; i < 3; i++) {
// Each argument to this attribute can either be a literal, an identifier for a module-scope
// constants, or nullptr if not specified.
auto* value = values[i];
@@ -757,7 +889,7 @@
}
auto* ty = expr->Type();
if (!ty->IsAnyOf<sem::I32, sem::U32, sem::AbstractInt>()) {
- AddError(kErrBadType, value->source);
+ AddError(kErrBadExpr, value->source);
return false;
}
@@ -784,13 +916,13 @@
return false;
}
- sem::Constant value;
+ const sem::Constant* value = nullptr;
if (auto* user = args[i]->As<sem::VariableUser>()) {
// We have an variable of a module-scope constant.
auto* decl = user->Variable()->Declaration();
- if (!decl->IsAnyOf<ast::Let, ast::Override>()) {
- AddError(kErrBadType, values[i]->source);
+ if (!decl->IsAnyOf<ast::Const, ast::Override>()) {
+ AddError(kErrBadExpr, values[i]->source);
return false;
}
// Capture the constant if it is pipeline-overridable.
@@ -808,10 +940,7 @@
} else if (values[i]->Is<ast::LiteralExpression>()) {
value = materialized->ConstantValue();
} else {
- AddError(
- "workgroup_size argument must be either a literal or a "
- "module-scope constant",
- values[i]->source);
+ AddError(kErrBadExpr, values[i]->source);
return false;
}
@@ -821,12 +950,12 @@
continue;
}
// validator_.Validate and set the default value for this dimension.
- if (value.Element<AInt>(0).value < 1) {
+ if (value->As<AInt>() < 1) {
AddError("workgroup_size argument must be at least 1", values[i]->source);
return false;
}
- ws[i].value = value.Element<uint32_t>(0);
+ ws[i].value = value->As<uint32_t>();
}
current_function_->SetWorkgroupSize(std::move(ws));
@@ -1137,7 +1266,8 @@
[&](const ast::UnaryOpExpression* unary) -> sem::Expression* { return UnaryOp(unary); },
[&](const ast::PhonyExpression*) -> sem::Expression* {
return builder_->create<sem::Expression>(expr, builder_->create<sem::Void>(),
- current_statement_, sem::Constant{},
+ current_statement_,
+ /* constant_value */ nullptr,
/* has_side_effects */ false);
},
[&](Default) {
@@ -1168,23 +1298,24 @@
// Helper for actually creating the the materialize node, performing the constant cast, updating
// the ast -> sem binding, and performing validation.
auto materialize = [&](const sem::Type* target_ty) -> sem::Materialize* {
+ auto* src_ty = expr->Type();
auto* decl = expr->Declaration();
+ if (!validator_.Materialize(target_ty, src_ty, decl->source)) {
+ return nullptr;
+ }
auto expr_val = EvaluateConstantValue(decl, expr->Type());
if (!expr_val) {
- return nullptr;
- }
- if (!expr_val->IsValid()) {
TINT_ICE(Resolver, builder_->Diagnostics())
- << decl->source
- << "EvaluateConstantValue() returned invalid value for materialized value of type: "
- << builder_->FriendlyName(expr->Type());
+ << decl->source << "EvaluateConstantValue(" << decl->TypeInfo().name
+ << ") returned invalid value";
return nullptr;
}
- auto materialized_val = ConvertValue(expr_val.Get(), target_ty, decl->source);
+ auto materialized_val = ConvertValue(expr_val, target_ty, decl->source);
if (!materialized_val) {
+ // ConvertValue() has already failed and raised an diagnostic error.
return nullptr;
}
- if (!materialized_val->IsValid()) {
+ if (!materialized_val.Get()) {
TINT_ICE(Resolver, builder_->Diagnostics())
<< decl->source << "ConvertValue(" << builder_->FriendlyName(expr_val->Type())
<< " -> " << builder_->FriendlyName(target_ty) << ") returned invalid value";
@@ -1194,7 +1325,7 @@
builder_->create<sem::Materialize>(expr, current_statement_, materialized_val.Get());
m->Behaviors() = expr->Behaviors();
builder_->Sem().Replace(decl, m);
- return validator_.Materialize(m) ? m : nullptr;
+ return m;
};
// Helpers for constructing semantic types
@@ -1289,12 +1420,10 @@
}
auto val = EvaluateConstantValue(expr, ty);
- if (!val) {
- return nullptr;
- }
bool has_side_effects = idx->HasSideEffects() || obj->HasSideEffects();
- auto* sem = builder_->create<sem::Expression>(expr, ty, current_statement_, val.Get(),
- has_side_effects, obj->SourceVariable());
+ auto* sem = builder_->create<sem::IndexAccessorExpression>(
+ expr, ty, obj, idx, current_statement_, std::move(val), has_side_effects,
+ obj->SourceVariable());
sem->Behaviors() = idx->Behaviors() + obj->Behaviors();
return sem;
}
@@ -1310,10 +1439,7 @@
}
auto val = EvaluateConstantValue(expr, ty);
- if (!val) {
- return nullptr;
- }
- auto* sem = builder_->create<sem::Expression>(expr, ty, current_statement_, val.Get(),
+ auto* sem = builder_->create<sem::Expression>(expr, ty, current_statement_, std::move(val),
inner->HasSideEffects());
sem->Behaviors() = inner->Behaviors();
@@ -1361,11 +1487,8 @@
return nullptr;
}
auto val = EvaluateConstantValue(expr, call_target->ReturnType());
- if (!val) {
- return nullptr;
- }
return builder_->create<sem::Call>(expr, call_target, std::move(args), current_statement_,
- val.Get(), has_side_effects);
+ std::move(val), has_side_effects);
};
// ct_ctor_or_conv is a helper for building either a sem::TypeConstructor or sem::TypeConversion
@@ -1381,6 +1504,7 @@
},
[&](const sem::I32*) { return ct_ctor_or_conv(CtorConvIntrinsic::kI32, nullptr); },
[&](const sem::U32*) { return ct_ctor_or_conv(CtorConvIntrinsic::kU32, nullptr); },
+ [&](const sem::F16*) { return ct_ctor_or_conv(CtorConvIntrinsic::kF16, nullptr); },
[&](const sem::F32*) { return ct_ctor_or_conv(CtorConvIntrinsic::kF32, nullptr); },
[&](const sem::Bool*) { return ct_ctor_or_conv(CtorConvIntrinsic::kBool, nullptr); },
[&](const sem::Array* arr) -> sem::Call* {
@@ -1402,11 +1526,9 @@
return nullptr;
}
auto val = EvaluateConstantValue(expr, call_target->ReturnType());
- if (!val) {
- return nullptr;
- }
return builder_->create<sem::Call>(expr, call_target, std::move(args),
- current_statement_, val.Get(), has_side_effects);
+ current_statement_, std::move(val),
+ has_side_effects);
},
[&](const sem::Struct* str) -> sem::Call* {
auto* call_target = utils::GetOrCreate(
@@ -1427,11 +1549,9 @@
return nullptr;
}
auto val = EvaluateConstantValue(expr, call_target->ReturnType());
- if (!val) {
- return nullptr;
- }
return builder_->create<sem::Call>(expr, call_target, std::move(args),
- current_statement_, val.Get(), has_side_effects);
+ current_statement_, std::move(val),
+ has_side_effects);
},
[&](Default) {
AddError("type is not constructible", expr->source);
@@ -1560,9 +1680,9 @@
}
// If the builtin is @const, and all arguments have constant values, evaluate the builtin now.
- sem::Constant constant;
+ const sem::Constant* constant = nullptr;
if (builtin.const_eval_fn) {
- std::vector<sem::Constant> values(args.size());
+ std::vector<const sem::Constant*> values(args.size());
bool is_const = true; // all arguments have constant values
for (size_t i = 0; i < values.size(); i++) {
if (auto v = args[i]->ConstantValue()) {
@@ -1613,12 +1733,13 @@
if (texture_index == -1) {
TINT_ICE(Resolver, diagnostics_) << "texture builtin without texture parameter";
}
- auto* texture = args[texture_index]->As<sem::VariableUser>()->Variable();
+ auto* texture = args[static_cast<size_t>(texture_index)]->As<sem::VariableUser>()->Variable();
if (!texture->Type()->UnwrapRef()->Is<sem::StorageTexture>()) {
int sampler_index = signature.IndexOf(sem::ParameterUsage::kSampler);
const sem::Variable* sampler =
- sampler_index != -1 ? args[sampler_index]->As<sem::VariableUser>()->Variable()
- : nullptr;
+ sampler_index != -1
+ ? args[static_cast<size_t>(sampler_index)]->As<sem::VariableUser>()->Variable()
+ : nullptr;
current_function_->AddTextureSamplerPair(texture, sampler);
}
}
@@ -1638,7 +1759,7 @@
// effects.
bool has_side_effects = true;
auto* call = builder_->create<sem::Call>(expr, target, std::move(args), current_statement_,
- sem::Constant{}, has_side_effects);
+ /* constant_value */ nullptr, has_side_effects);
target->AddCallSite(call);
@@ -1733,18 +1854,15 @@
}
auto val = EvaluateConstantValue(literal, ty);
- if (!val) {
- return nullptr;
- }
- return builder_->create<sem::Expression>(literal, ty, current_statement_, val.Get(),
+ return builder_->create<sem::Expression>(literal, ty, current_statement_, std::move(val),
/* has_side_effects */ false);
}
sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
auto symbol = expr->symbol;
auto* resolved = sem_.ResolvedSymbol(expr);
- if (auto* var = As<sem::Variable>(resolved)) {
- auto* user = builder_->create<sem::VariableUser>(expr, current_statement_, var);
+ if (auto* variable = As<sem::Variable>(resolved)) {
+ auto* user = builder_->create<sem::VariableUser>(expr, current_statement_, variable);
if (current_statement_) {
// If identifier is part of a loop continuing block, make sure it
@@ -1780,12 +1898,20 @@
}
if (current_function_) {
- if (auto* global = var->As<sem::GlobalVariable>()) {
+ if (auto* global = variable->As<sem::GlobalVariable>()) {
current_function_->AddDirectlyReferencedGlobal(global);
}
+ } else if (variable->Declaration()->Is<ast::Var>()) {
+ // Use of a module-scope 'var' outside of a function.
+ // Note: The spec is currently vague around the rules here. See
+ // https://github.com/gpuweb/gpuweb/issues/3081. Remove this comment when resolved.
+ std::string desc = "var '" + builder_->Symbols().NameFor(symbol) + "' ";
+ AddError(desc + "cannot not be referenced at module-scope", expr->source);
+ AddNote(desc + "declared here", variable->Declaration()->source);
+ return nullptr;
}
- var->AddUser(user);
+ variable->AddUser(user);
return user;
}
@@ -1819,9 +1945,9 @@
const sem::Type* ret = nullptr;
std::vector<uint32_t> swizzle;
- // Structure may be a side-effecting expression (e.g. function call).
- auto* sem_structure = sem_.Get(expr->structure);
- bool has_side_effects = sem_structure && sem_structure->HasSideEffects();
+ // Object may be a side-effecting expression (e.g. function call).
+ auto* object = sem_.Get(expr->structure);
+ bool has_side_effects = object && object->HasSideEffects();
if (auto* str = storage_ty->As<sem::Struct>()) {
Mark(expr->member);
@@ -1847,8 +1973,8 @@
ret = builder_->create<sem::Reference>(ret, ref->StorageClass(), ref->Access());
}
- return builder_->create<sem::StructMemberAccess>(expr, ret, current_statement_, member,
- has_side_effects, source_var);
+ return builder_->create<sem::StructMemberAccess>(expr, ret, current_statement_, object,
+ member, has_side_effects, source_var);
}
if (auto* vec = storage_ty->As<sem::Vector>()) {
@@ -1914,8 +2040,8 @@
// the swizzle.
ret = builder_->create<sem::Vector>(vec->type(), static_cast<uint32_t>(size));
}
- return builder_->create<sem::Swizzle>(expr, ret, current_statement_, std::move(swizzle),
- has_side_effects, source_var);
+ return builder_->create<sem::Swizzle>(expr, ret, current_statement_, object,
+ std::move(swizzle), has_side_effects, source_var);
}
AddError("invalid member accessor expression. Expected vector or struct, got '" +
@@ -1948,12 +2074,9 @@
}
auto val = EvaluateConstantValue(expr, op.result);
- if (!val) {
- return nullptr;
- }
bool has_side_effects = lhs->HasSideEffects() || rhs->HasSideEffects();
- auto* sem = builder_->create<sem::Expression>(expr, op.result, current_statement_, val.Get(),
- has_side_effects);
+ auto* sem = builder_->create<sem::Expression>(expr, op.result, current_statement_,
+ std::move(val), has_side_effects);
sem->Behaviors() = lhs->Behaviors() + rhs->Behaviors();
return sem;
@@ -2025,10 +2148,7 @@
}
auto val = EvaluateConstantValue(unary, ty);
- if (!val) {
- return nullptr;
- }
- auto* sem = builder_->create<sem::Expression>(unary, ty, current_statement_, val.Get(),
+ auto* sem = builder_->create<sem::Expression>(unary, ty, current_statement_, std::move(val),
expr->HasSideEffects(), source_var);
sem->Behaviors() = expr->Behaviors();
return sem;
@@ -2099,69 +2219,47 @@
uint64_t stride = explicit_stride ? explicit_stride : implicit_stride;
+ int64_t count = 0; // sem::Array uses a size of 0 for a runtime-sized array.
+
// Evaluate the constant array size expression.
- // sem::Array uses a size of 0 for a runtime-sized array.
- uint32_t count = 0;
if (auto* count_expr = arr->count) {
const auto* count_sem = Materialize(Expression(count_expr));
if (!count_sem) {
return nullptr;
}
- auto size_source = count_expr->source;
-
- auto* ty = count_sem->Type()->UnwrapRef();
- if (!ty->is_integer_scalar()) {
- AddError("array size must be integer scalar", size_source);
- return nullptr;
- }
-
- constexpr const char* kErrInvalidExpr =
- "array size identifier must be a literal or a module-scope 'let'";
-
- if (auto* ident = count_expr->As<ast::IdentifierExpression>()) {
- // Make sure the identifier is a non-overridable module-scope 'let'.
- auto* global = sem_.ResolvedSymbol<sem::GlobalVariable>(ident);
- if (!global || !global->Declaration()->Is<ast::Let>()) {
- AddError(kErrInvalidExpr, size_source);
- return nullptr;
- }
- count_expr = global->Declaration()->constructor;
- } else if (!count_expr->Is<ast::LiteralExpression>()) {
- AddError(kErrInvalidExpr, size_source);
- return nullptr;
- }
-
- auto count_val = count_sem->ConstantValue();
+ auto* count_val = count_sem->ConstantValue();
if (!count_val) {
- TINT_ICE(Resolver, diagnostics_) << "could not resolve array size expression";
+ AddError("array size must evaluate to a constant integer expression",
+ count_expr->source);
return nullptr;
}
- if (count_val.Element<AInt>(0).value < 1) {
- AddError("array size must be at least 1", size_source);
+ if (auto* ty = count_val->Type(); !ty->is_integer_scalar()) {
+ AddError("array size must evaluate to a constant integer expression, but is type '" +
+ builder_->FriendlyName(ty) + "'",
+ count_expr->source);
return nullptr;
}
- count = count_val.Element<uint32_t>(0);
+ count = count_val->As<AInt>();
+ if (count < 1) {
+ AddError("array size (" + std::to_string(count) + ") must be greater than 0",
+ count_expr->source);
+ return nullptr;
+ }
}
- auto size = std::max<uint64_t>(count, 1) * stride;
+ auto size = std::max<uint64_t>(static_cast<uint32_t>(count), 1u) * stride;
if (size > std::numeric_limits<uint32_t>::max()) {
std::stringstream msg;
- msg << "array size in bytes must not exceed 0x" << std::hex
- << std::numeric_limits<uint32_t>::max() << ", but is 0x" << std::hex << size;
+ msg << "array size (0x" << std::hex << size << ") must not exceed 0xffffffff bytes";
AddError(msg.str(), arr->source);
return nullptr;
}
- if (stride > std::numeric_limits<uint32_t>::max() ||
- implicit_stride > std::numeric_limits<uint32_t>::max()) {
- TINT_ICE(Resolver, diagnostics_) << "calculated array stride exceeds uint32";
- return nullptr;
- }
auto* out = builder_->create<sem::Array>(
- elem_type, count, el_align, static_cast<uint32_t>(size), static_cast<uint32_t>(stride),
- static_cast<uint32_t>(implicit_stride));
+ elem_type, static_cast<uint32_t>(count), el_align, static_cast<uint32_t>(size),
+ static_cast<uint32_t>(stride), static_cast<uint32_t>(implicit_stride));
if (!validator_.Array(out, source)) {
return nullptr;
@@ -2289,8 +2387,8 @@
offset = utils::RoundUp(align, offset);
if (offset > std::numeric_limits<uint32_t>::max()) {
std::stringstream msg;
- msg << "struct member has byte offset 0x" << std::hex << offset
- << ", but must not exceed 0x" << std::hex << std::numeric_limits<uint32_t>::max();
+ msg << "struct member offset (0x" << std::hex << offset << ") must not exceed 0x"
+ << std::hex << std::numeric_limits<uint32_t>::max() << " bytes";
AddError(msg.str(), member->source);
return nullptr;
}
@@ -2311,8 +2409,7 @@
if (struct_size > std::numeric_limits<uint32_t>::max()) {
std::stringstream msg;
- msg << "struct size in bytes must not exceed 0x" << std::hex
- << std::numeric_limits<uint32_t>::max() << ", but is 0x" << std::hex << struct_size;
+ msg << "struct size (0x" << std::hex << struct_size << ") must not exceed 0xffffffff bytes";
AddError(msg.str(), str->source);
return nullptr;
}
@@ -2337,6 +2434,8 @@
break;
}
}
+
+ const_cast<sem::StructMember*>(sem_members[i])->SetStruct(out);
}
auto stage = current_function_ ? current_function_->Declaration()->PipelineStage()
@@ -2449,8 +2548,8 @@
return StatementScope(stmt, sem, [&] {
Mark(stmt->variable);
- auto* var = Variable(stmt->variable, /* is_global */ false);
- if (!var) {
+ auto* variable = Variable(stmt->variable, /* is_global */ false);
+ if (!variable) {
return false;
}
@@ -2466,11 +2565,11 @@
current_block_->AddDecl(stmt->variable);
}
- if (auto* ctor = var->Constructor()) {
+ if (auto* ctor = variable->Constructor()) {
sem->Behaviors() = ctor->Behaviors();
}
- return validator_.Variable(var);
+ return validator_.Variable(variable);
});
}
diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h
index e75c952..1a45bc4 100644
--- a/src/tint/resolver/resolver.h
+++ b/src/tint/resolver/resolver.h
@@ -171,17 +171,25 @@
const ast::ExpressionList& params,
uint32_t* id);
- //////////////////////////////////////////////////////////////////////////////
- // AST and Type traversal methods
- //////////////////////////////////////////////////////////////////////////////
+ /// Expression traverses the graph of expressions starting at `expr`, building a postordered
+ /// list (leaf-first) of all the expression nodes. Each of the expressions are then resolved by
+ /// dispatching to the appropriate expression handlers below.
+ /// @returns the resolved semantic node for the expression `expr`, or nullptr on failure.
+ sem::Expression* Expression(const ast::Expression* expr);
+ ////////////////////////////////////////////////////////////////////////////////////////////////
// Expression resolving methods
+ //
// Returns the semantic node pointer on success, nullptr on failure.
+ //
+ // These methods are invoked by Expression(), in postorder (child-first). These methods should
+ // not attempt to resolve their children. This design avoids recursion, which is a common cause
+ // of stack-overflows.
+ ////////////////////////////////////////////////////////////////////////////////////////////////
sem::Expression* IndexAccessor(const ast::IndexAccessorExpression*);
sem::Expression* Binary(const ast::BinaryExpression*);
sem::Expression* Bitcast(const ast::BitcastExpression*);
sem::Call* Call(const ast::CallExpression*);
- sem::Expression* Expression(const ast::Expression*);
sem::Function* Function(const ast::Function*);
sem::Call* FunctionCall(const ast::CallExpression*,
sem::Function* target,
@@ -195,6 +203,39 @@
sem::Expression* MemberAccessor(const ast::MemberAccessorExpression*);
sem::Expression* UnaryOp(const ast::UnaryOpExpression*);
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ /// Constant value evaluation methods
+ ///
+ /// These methods are called from the expression resolving methods, and so child-expression
+ /// nodes are guaranteed to have been already resolved and any constant values calculated.
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ const sem::Constant* EvaluateConstantValue(const ast::Expression* expr, const sem::Type* type);
+ const sem::Constant* EvaluateConstantValue(const ast::IdentifierExpression* ident,
+ const sem::Type* type);
+ const sem::Constant* EvaluateConstantValue(const ast::LiteralExpression* literal,
+ const sem::Type* type);
+ const sem::Constant* EvaluateConstantValue(const ast::CallExpression* call,
+ const sem::Type* type);
+ const sem::Constant* EvaluateConstantValue(const ast::IndexAccessorExpression* call,
+ const sem::Type* type);
+
+ /// The result type of a ConstantEvaluation method.
+ /// Can be one of three distinct values:
+ /// * A non-null sem::Constant pointer. Returned when a expression resolves to a creation time
+ /// value.
+ /// * A null sem::Constant pointer. Returned when a expression cannot resolve to a creation time
+ /// value, but is otherwise legal.
+ /// * `utils::Failure`. Returned when there was a resolver error. In this situation the method
+ /// will have already reported a diagnostic error message, and the caller should abort
+ /// resolving.
+ using ConstantResult = utils::Result<const sem::Constant*>;
+
+ /// Convert the `value` to `target_type`
+ /// @return the converted value
+ ConstantResult ConvertValue(const sem::Constant* value,
+ const sem::Type* target_type,
+ const Source& source);
+
/// If `expr` is not of an abstract-numeric type, then Materialize() will just return `expr`.
/// If `expr` is of an abstract-numeric type:
/// * Materialize will create and return a sem::Materialize node wrapping `expr`.
@@ -298,6 +339,37 @@
/// @param is_global true if this is module scope, otherwise function scope
sem::Variable* Variable(const ast::Variable* var, bool is_global);
+ /// @returns the semantic info for the `ast::Let` `v`. If an error is raised, nullptr is
+ /// returned.
+ /// @note this method does not resolve the attributes as these are context-dependent (global,
+ /// local)
+ /// @param var the variable
+ /// @param is_global true if this is module scope, otherwise function scope
+ sem::Variable* Let(const ast::Let* var, bool is_global);
+
+ /// @returns the semantic info for the module-scope `ast::Override` `v`. If an error is raised,
+ /// nullptr is returned.
+ /// @note this method does not resolve the attributes as these are context-dependent (global,
+ /// local)
+ /// @param override the variable
+ sem::Variable* Override(const ast::Override* override);
+
+ /// @returns the semantic info for an `ast::Const` `v`. If an error is raised, nullptr is
+ /// returned.
+ /// @note this method does not resolve the attributes as these are context-dependent (global,
+ /// local)
+ /// @param const_ the variable
+ /// @param is_global true if this is module scope, otherwise function scope
+ sem::Variable* Const(const ast::Const* const_, bool is_global);
+
+ /// @returns the semantic info for the `ast::Var` `var`. If an error is raised, nullptr is
+ /// returned.
+ /// @note this method does not resolve the attributes as these are context-dependent (global,
+ /// local)
+ /// @param var the variable
+ /// @param is_global true if this is module scope, otherwise function scope
+ sem::Variable* Var(const ast::Var* var, bool is_global);
+
/// @returns the semantic info for the function parameter `param`. If an error is raised,
/// nullptr is returned.
/// @note the caller is expected to validate the parameter
@@ -356,23 +428,6 @@
/// Adds the given note message to the diagnostics
void AddNote(const std::string& msg, const Source& source) const;
- //////////////////////////////////////////////////////////////////////////////
- /// Constant value evaluation methods
- //////////////////////////////////////////////////////////////////////////////
- /// The result type of a ConstantEvaluation method. Holds the constant value and a boolean,
- /// which is true on success, false on an error.
- using ConstantResult = utils::Result<sem::Constant>;
-
- /// Convert the `value` to `target_type`
- /// @return the converted value
- ConstantResult ConvertValue(const sem::Constant& value,
- const sem::Type* target_type,
- const Source& source);
- ConstantResult EvaluateConstantValue(const ast::Expression* expr, const sem::Type* type);
- ConstantResult EvaluateConstantValue(const ast::LiteralExpression* literal,
- const sem::Type* type);
- ConstantResult EvaluateConstantValue(const ast::CallExpression* call, const sem::Type* type);
-
/// @returns true if the symbol is the name of a builtin function.
bool IsBuiltin(Symbol) const;
diff --git a/src/tint/resolver/resolver_constants.cc b/src/tint/resolver/resolver_constants.cc
index 24c57d4..f6ffb28 100644
--- a/src/tint/resolver/resolver_constants.cc
+++ b/src/tint/resolver/resolver_constants.cc
@@ -14,7 +14,6 @@
#include "src/tint/resolver/resolver.h"
-#include <cmath>
#include <optional>
#include "src/tint/sem/abstract_float.h"
@@ -22,8 +21,6 @@
#include "src/tint/sem/constant.h"
#include "src/tint/sem/type_constructor.h"
#include "src/tint/utils/compiler_macros.h"
-#include "src/tint/utils/map.h"
-#include "src/tint/utils/transform.h"
using namespace tint::number_suffixes; // NOLINT
@@ -31,244 +28,559 @@
namespace {
-/// Converts and returns all the element values of `in` to the type `T`, using the converter
-/// function `CONVERTER`.
-/// @param elements_in the vector of elements to be converted
-/// @param converter a function-like with the signature `void(TO&, FROM)`
-/// @returns the elements converted to type T.
-template <typename T, typename ELEMENTS_IN, typename CONVERTER>
-sem::Constant::Elements Transform(const ELEMENTS_IN& elements_in, CONVERTER&& converter) {
- TINT_BEGIN_DISABLE_WARNING(UNREACHABLE_CODE);
+/// TypeDispatch is a helper for calling the function `f`, passing a single zero-value argument of
+/// the C++ type that corresponds to the sem::Type `type`. For example, calling `TypeDispatch()`
+/// with a type of `sem::I32*` will call the function f with a single argument of `i32(0)`.
+/// @returns the value returned by calling `f`.
+/// @note `type` must be a scalar or abstract numeric type. Other types will not call `f`, and will
+/// return the zero-initialized value of the return type for `f`.
+template <typename F>
+auto TypeDispatch(const sem::Type* type, F&& f) {
+ return Switch(
+ type, //
+ [&](const sem::AbstractInt*) { return f(AInt(0)); }, //
+ [&](const sem::AbstractFloat*) { return f(AFloat(0)); }, //
+ [&](const sem::I32*) { return f(i32(0)); }, //
+ [&](const sem::U32*) { return f(u32(0)); }, //
+ [&](const sem::F32*) { return f(f32(0)); }, //
+ [&](const sem::F16*) { return f(f16(0)); }, //
+ [&](const sem::Bool*) { return f(static_cast<bool>(0)); });
+}
- return utils::Transform(elements_in, [&](auto value_in) {
- if constexpr (std::is_same_v<UnwrapNumber<T>, bool>) {
- return AInt(value_in != 0);
+/// @returns `value` if `T` is not a Number, otherwise ValueOf returns the inner value of the
+/// Number.
+template <typename T>
+inline auto ValueOf(T value) {
+ if constexpr (std::is_same_v<UnwrapNumber<T>, T>) {
+ return value;
+ } else {
+ return value.value;
+ }
+}
+
+/// @returns true if `value` is a positive zero.
+template <typename T>
+inline bool IsPositiveZero(T value) {
+ using N = UnwrapNumber<T>;
+ return Number<N>(value) == Number<N>(0); // Considers sign bit
+}
+
+/// Constant inherits from sem::Constant to add an private implementation method for conversion.
+struct Constant : public sem::Constant {
+ /// Convert attempts to convert the constant value to the given type. On error, Convert()
+ /// creates a new diagnostic message and returns a Failure.
+ virtual utils::Result<const Constant*> Convert(ProgramBuilder& builder,
+ const sem::Type* target_ty,
+ const Source& source) const = 0;
+};
+
+// Forward declaration
+const Constant* CreateComposite(ProgramBuilder& builder,
+ const sem::Type* type,
+ std::vector<const Constant*> elements);
+
+/// Element holds a single scalar or abstract-numeric value.
+/// Element implements the Constant interface.
+template <typename T>
+struct Element : Constant {
+ Element(const sem::Type* t, T v) : type(t), value(v) {}
+ ~Element() override = default;
+ const sem::Type* Type() const override { return type; }
+ std::variant<std::monostate, AInt, AFloat> Value() const override {
+ if constexpr (IsFloatingPoint<UnwrapNumber<T>>) {
+ return static_cast<AFloat>(value);
} else {
- T converted{};
- converter(converted, value_in);
- if constexpr (IsFloatingPoint<UnwrapNumber<T>>) {
- return AFloat(converted);
+ return static_cast<AInt>(value);
+ }
+ }
+ const Constant* Index(size_t) const override { return nullptr; }
+ bool AllZero() const override { return IsPositiveZero(value); }
+ bool AnyZero() const override { return IsPositiveZero(value); }
+ bool AllEqual() const override { return true; }
+ size_t Hash() const override { return utils::Hash(type, ValueOf(value)); }
+
+ utils::Result<const Constant*> Convert(ProgramBuilder& builder,
+ const sem::Type* target_ty,
+ const Source& source) const override {
+ TINT_BEGIN_DISABLE_WARNING(UNREACHABLE_CODE);
+ if (target_ty == type) {
+ // If the types are identical, then no conversion is needed.
+ return this;
+ }
+ bool failed = false;
+ auto* res = TypeDispatch(target_ty, [&](auto zero_to) -> const Constant* {
+ // `T` is the source type, `value` is the source value.
+ // `TO` is the target type.
+ using TO = std::decay_t<decltype(zero_to)>;
+ if constexpr (std::is_same_v<TO, bool>) {
+ // [x -> bool]
+ return builder.create<Element<TO>>(target_ty, !IsPositiveZero(value));
+ } else if constexpr (std::is_same_v<T, bool>) {
+ // [bool -> x]
+ return builder.create<Element<TO>>(target_ty, TO(value ? 1 : 0));
+ } else if (auto conv = CheckedConvert<TO>(value)) {
+ // Conversion success
+ return builder.create<Element<TO>>(target_ty, conv.Get());
+ // --- Below this point are the failure cases ---
+ } else if constexpr (std::is_same_v<T, AInt> || std::is_same_v<T, AFloat>) {
+ // [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);
+ failed = true;
+ } else if constexpr (IsFloatingPoint<UnwrapNumber<TO>>) {
+ // [x -> floating-point] - number not exactly representable
+ // https://www.w3.org/TR/WGSL/#floating-point-conversion
+ constexpr auto kInf = std::numeric_limits<double>::infinity();
+ switch (conv.Failure()) {
+ case ConversionFailure::kExceedsNegativeLimit:
+ return builder.create<Element<TO>>(target_ty, TO(-kInf));
+ case ConversionFailure::kExceedsPositiveLimit:
+ return builder.create<Element<TO>>(target_ty, TO(kInf));
+ }
} else {
- return AInt(converted);
+ // [x -> integer] - number not exactly representable
+ // https://www.w3.org/TR/WGSL/#floating-point-conversion
+ switch (conv.Failure()) {
+ case ConversionFailure::kExceedsNegativeLimit:
+ return builder.create<Element<TO>>(target_ty, TO(TO::kLowest));
+ case ConversionFailure::kExceedsPositiveLimit:
+ return builder.create<Element<TO>>(target_ty, TO(TO::kHighest));
+ }
}
+ return nullptr; // Expression is not constant.
+ });
+ if (failed) {
+ // A diagnostic error has been raised, and resolving should abort.
+ return utils::Failure;
}
- });
-
- TINT_END_DISABLE_WARNING(UNREACHABLE_CODE);
-}
-
-/// Converts and returns all the element values of `in` to the semantic type `el_ty`, using the
-/// converter function `CONVERTER`.
-/// @param in the constant to convert
-/// @param el_ty the target element type
-/// @param converter a function-like with the signature `void(TO&, FROM)`
-/// @returns the elements converted to `el_ty`
-template <typename CONVERTER>
-sem::Constant::Elements Transform(const sem::Constant::Elements& in,
- const sem::Type* el_ty,
- CONVERTER&& converter) {
- return std::visit(
- [&](auto&& v) {
- return Switch(
- el_ty, //
- [&](const sem::AbstractInt*) { return Transform<AInt>(v, converter); },
- [&](const sem::AbstractFloat*) { return Transform<AFloat>(v, converter); },
- [&](const sem::I32*) { return Transform<i32>(v, converter); },
- [&](const sem::U32*) { return Transform<u32>(v, converter); },
- [&](const sem::F32*) { return Transform<f32>(v, converter); },
- [&](const sem::F16*) { return Transform<f16>(v, converter); },
- [&](const sem::Bool*) { return Transform<bool>(v, converter); },
- [&](Default) -> sem::Constant::Elements {
- diag::List diags;
- TINT_UNREACHABLE(Semantic, diags)
- << "invalid element type " << el_ty->TypeInfo().name;
- return {};
- });
- },
- in);
-}
-
-/// Converts and returns all the elements in `in` to the type `el_ty`.
-/// If the value does not fit in the target type, and:
-/// * the target type is an integer type, then the resulting value will be clamped to the integer's
-/// highest or lowest value.
-/// * the target type is an float type, then the resulting value will be either positive or
-/// negative infinity, based on the sign of the input value.
-/// @param in the input elements
-/// @param el_ty the target element type
-/// @returns the elements converted to `el_ty`
-sem::Constant::Elements ConvertElements(const sem::Constant::Elements& in, const sem::Type* el_ty) {
- return Transform(in, el_ty, [](auto& el_out, auto el_in) {
- using OUT = std::decay_t<decltype(el_out)>;
- if (auto conv = CheckedConvert<OUT>(el_in)) {
- el_out = conv.Get();
- } else {
- constexpr auto kInf = std::numeric_limits<double>::infinity();
- switch (conv.Failure()) {
- case ConversionFailure::kExceedsNegativeLimit:
- el_out = IsFloatingPoint<UnwrapNumber<OUT>> ? OUT(-kInf) : OUT::kLowest;
- break;
- case ConversionFailure::kExceedsPositiveLimit:
- el_out = IsFloatingPoint<UnwrapNumber<OUT>> ? OUT(kInf) : OUT::kHighest;
- break;
- }
- }
- });
-}
-
-/// Converts and returns all the elements in `in` to the type `el_ty`, by performing a
-/// `CheckedConvert` on each element value. A single error diagnostic will be raised if an element
-/// value cannot be represented by the target type.
-/// @param in the input elements
-/// @param el_ty the target element type
-/// @returns the elements converted to `el_ty`, or a Failure if some elements could not be
-/// represented by the target type.
-utils::Result<sem::Constant::Elements> MaterializeElements(const sem::Constant::Elements& in,
- const sem::Type* el_ty,
- ProgramBuilder& builder,
- Source source) {
- std::optional<std::string> failure;
-
- auto out = Transform(in, el_ty, [&](auto& el_out, auto el_in) {
- using OUT = std::decay_t<decltype(el_out)>;
- if (auto conv = CheckedConvert<OUT>(el_in)) {
- el_out = conv.Get();
- } else if (!failure.has_value()) {
- std::stringstream ss;
- ss << "value " << el_in << " cannot be represented as ";
- ss << "'" << builder.FriendlyName(el_ty) << "'";
- failure = ss.str();
- }
- });
-
- if (failure.has_value()) {
- builder.Diagnostics().add_error(diag::System::Resolver, std::move(failure.value()), source);
- return utils::Failure;
+ return res;
+ TINT_END_DISABLE_WARNING(UNREACHABLE_CODE);
}
- return out;
+ sem::Type const* const type;
+ const T value;
+};
+
+/// Splat holds a single Constant value, duplicated as all children.
+/// Splat is used for zero-initializers, 'splat' constructors, or constructors where each element is
+/// identical. Splat may be of a vector, matrix or array type.
+/// Splat implements the Constant interface.
+struct Splat : Constant {
+ Splat(const sem::Type* t, const Constant* e, size_t n) : type(t), el(e), count(n) {}
+ ~Splat() override = default;
+ const sem::Type* Type() const override { return type; }
+ std::variant<std::monostate, AInt, AFloat> Value() const override { return {}; }
+ const Constant* Index(size_t i) const override { return i < count ? el : nullptr; }
+ bool AllZero() const override { return el->AllZero(); }
+ bool AnyZero() const override { return el->AnyZero(); }
+ bool AllEqual() const override { return true; }
+ size_t Hash() const override { return utils::Hash(type, el->Hash(), count); }
+
+ utils::Result<const Constant*> Convert(ProgramBuilder& builder,
+ const sem::Type* target_ty,
+ const Source& source) const override {
+ // Convert the single splatted element type.
+ auto conv_el = el->Convert(builder, sem::Type::ElementOf(target_ty), source);
+ if (!conv_el) {
+ return utils::Failure;
+ }
+ if (!conv_el.Get()) {
+ return nullptr;
+ }
+ return builder.create<Splat>(target_ty, conv_el.Get(), count);
+ }
+
+ sem::Type const* const type;
+ const Constant* el;
+ const size_t count;
+};
+
+/// Composite holds a number of mixed child Constant values.
+/// Composite may be of a vector, matrix or array type.
+/// If each element is the same type and value, then a Splat would be a more efficient constant
+/// implementation. Use CreateComposite() to create the appropriate Constant type.
+/// Composite implements the Constant interface.
+struct Composite : Constant {
+ Composite(const sem::Type* t, std::vector<const Constant*> els, bool all_0, bool any_0)
+ : type(t), elements(std::move(els)), all_zero(all_0), any_zero(any_0), hash(CalcHash()) {}
+ ~Composite() override = default;
+ const sem::Type* Type() const override { return type; }
+ std::variant<std::monostate, AInt, AFloat> Value() const override { return {}; }
+ const Constant* Index(size_t i) const override {
+ return i < elements.size() ? elements[i] : nullptr;
+ }
+ bool AllZero() const override { return all_zero; }
+ bool AnyZero() const override { return any_zero; }
+ bool AllEqual() const override { return false; /* otherwise this should be a Splat */ }
+ size_t Hash() const override { return hash; }
+
+ utils::Result<const Constant*> Convert(ProgramBuilder& builder,
+ const sem::Type* target_ty,
+ const Source& source) const override {
+ // Convert each of the composite element types.
+ auto* el_ty = sem::Type::ElementOf(target_ty);
+ std::vector<const Constant*> conv_els;
+ conv_els.reserve(elements.size());
+ for (auto* el : elements) {
+ auto conv_el = el->Convert(builder, el_ty, source);
+ if (!conv_el) {
+ return utils::Failure;
+ }
+ if (!conv_el.Get()) {
+ return nullptr;
+ }
+ conv_els.emplace_back(conv_el.Get());
+ }
+ return CreateComposite(builder, target_ty, std::move(conv_els));
+ }
+
+ size_t CalcHash() {
+ auto h = utils::Hash(type, all_zero, any_zero);
+ for (auto* el : elements) {
+ utils::HashCombine(&h, el->Hash());
+ }
+ return h;
+ }
+
+ sem::Type const* const type;
+ const std::vector<const Constant*> elements;
+ const bool all_zero;
+ const bool any_zero;
+ const size_t hash;
+};
+
+/// CreateElement constructs and returns an Element<T>.
+template <typename T>
+const Constant* CreateElement(ProgramBuilder& builder, const sem::Type* t, T v) {
+ return builder.create<Element<T>>(t, v);
+}
+
+/// ZeroValue returns a Constant for the zero-value of the type `type`.
+const Constant* ZeroValue(ProgramBuilder& builder, const sem::Type* type) {
+ return Switch(
+ type, //
+ [&](const sem::Vector* v) -> const Constant* {
+ auto* zero_el = ZeroValue(builder, v->type());
+ return builder.create<Splat>(type, zero_el, v->Width());
+ },
+ [&](const sem::Matrix* m) -> const Constant* {
+ auto* zero_el = ZeroValue(builder, m->ColumnType());
+ return builder.create<Splat>(type, zero_el, m->columns());
+ },
+ [&](const sem::Array* a) -> const Constant* {
+ if (auto* zero_el = ZeroValue(builder, a->ElemType())) {
+ return builder.create<Splat>(type, zero_el, a->Count());
+ }
+ return nullptr;
+ },
+ [&](Default) -> const Constant* {
+ return TypeDispatch(type, [&](auto zero) -> const Constant* {
+ return CreateElement(builder, type, zero);
+ });
+ });
+}
+
+/// Equal returns true if the constants `a` and `b` are of the same type and value.
+bool Equal(const sem::Constant* a, const sem::Constant* b) {
+ if (a->Hash() != b->Hash()) {
+ return false;
+ }
+ if (a->Type() != b->Type()) {
+ return false;
+ }
+ return Switch(
+ a->Type(), //
+ [&](const sem::Vector* vec) {
+ for (size_t i = 0; i < vec->Width(); i++) {
+ if (!Equal(a->Index(i), b->Index(i))) {
+ return false;
+ }
+ }
+ return true;
+ },
+ [&](const sem::Matrix* mat) {
+ for (size_t i = 0; i < mat->columns(); i++) {
+ if (!Equal(a->Index(i), b->Index(i))) {
+ return false;
+ }
+ }
+ return true;
+ },
+ [&](const sem::Array* arr) {
+ for (size_t i = 0; i < arr->Count(); i++) {
+ if (!Equal(a->Index(i), b->Index(i))) {
+ return false;
+ }
+ }
+ return true;
+ },
+ [&](Default) { return a->Value() == b->Value(); });
+}
+
+/// CreateComposite is used to construct a constant of a vector, matrix or array type.
+/// CreateComposite examines the element values and will return either a Composite or a Splat,
+/// depending on the element types and values.
+const Constant* CreateComposite(ProgramBuilder& builder,
+ const sem::Type* type,
+ std::vector<const Constant*> elements) {
+ if (elements.size() == 0) {
+ return nullptr;
+ }
+ bool any_zero = false;
+ bool all_zero = true;
+ bool all_equal = true;
+ auto* first = elements.front();
+ for (auto* el : elements) {
+ if (!any_zero && el->AnyZero()) {
+ any_zero = true;
+ }
+ if (all_zero && !el->AllZero()) {
+ all_zero = false;
+ }
+ if (all_equal && el != first) {
+ if (!Equal(el, first)) {
+ all_equal = false;
+ }
+ }
+ }
+ if (all_equal) {
+ return builder.create<Splat>(type, elements[0], elements.size());
+ } else {
+ return builder.create<Composite>(type, std::move(elements), all_zero, any_zero);
+ }
}
} // namespace
-utils::Result<sem::Constant> Resolver::EvaluateConstantValue(const ast::Expression* expr,
- const sem::Type* type) {
- if (auto* e = expr->As<ast::LiteralExpression>()) {
- return EvaluateConstantValue(e, type);
- }
- if (auto* e = expr->As<ast::CallExpression>()) {
- return EvaluateConstantValue(e, type);
- }
- return sem::Constant{};
+const sem::Constant* Resolver::EvaluateConstantValue(const ast::Expression* expr,
+ const sem::Type* type) {
+ return Switch(
+ expr, //
+ [&](const ast::IdentifierExpression* e) { return EvaluateConstantValue(e, type); },
+ [&](const ast::LiteralExpression* e) { return EvaluateConstantValue(e, type); },
+ [&](const ast::CallExpression* e) { return EvaluateConstantValue(e, type); },
+ [&](const ast::IndexAccessorExpression* e) { return EvaluateConstantValue(e, type); });
}
-utils::Result<sem::Constant> Resolver::EvaluateConstantValue(const ast::LiteralExpression* literal,
- const sem::Type* type) {
+const sem::Constant* Resolver::EvaluateConstantValue(const ast::IdentifierExpression* ident,
+ const sem::Type*) {
+ if (auto* sem = builder_->Sem().Get(ident)) {
+ return sem->ConstantValue();
+ }
+ return {};
+}
+
+const sem::Constant* Resolver::EvaluateConstantValue(const ast::LiteralExpression* literal,
+ const sem::Type* type) {
return Switch(
literal,
[&](const ast::BoolLiteralExpression* lit) {
- return sem::Constant{type, {AInt(lit->value ? 1 : 0)}};
+ return CreateElement(*builder_, type, lit->value);
},
- [&](const ast::IntLiteralExpression* lit) {
- return sem::Constant{type, {AInt(lit->value)}};
+ [&](const ast::IntLiteralExpression* lit) -> const Constant* {
+ switch (lit->suffix) {
+ case ast::IntLiteralExpression::Suffix::kNone:
+ return CreateElement(*builder_, type, AInt(lit->value));
+ case ast::IntLiteralExpression::Suffix::kI:
+ return CreateElement(*builder_, type, i32(lit->value));
+ case ast::IntLiteralExpression::Suffix::kU:
+ return CreateElement(*builder_, type, u32(lit->value));
+ }
+ return nullptr;
},
- [&](const ast::FloatLiteralExpression* lit) {
- return sem::Constant{type, {AFloat(lit->value)}};
+ [&](const ast::FloatLiteralExpression* lit) -> const Constant* {
+ switch (lit->suffix) {
+ case ast::FloatLiteralExpression::Suffix::kNone:
+ return CreateElement(*builder_, type, AFloat(lit->value));
+ case ast::FloatLiteralExpression::Suffix::kF:
+ return CreateElement(*builder_, type, f32(lit->value));
+ case ast::FloatLiteralExpression::Suffix::kH:
+ return CreateElement(*builder_, type, f16(lit->value));
+ }
+ return nullptr;
});
}
-utils::Result<sem::Constant> Resolver::EvaluateConstantValue(const ast::CallExpression* call,
- const sem::Type* ty) {
- uint32_t result_size = 0;
- auto* el_ty = sem::Type::ElementOf(ty, &result_size);
- if (!el_ty) {
- return sem::Constant{};
- }
-
- // ElementOf() will also return the element type of array, which we do not support.
- if (ty->Is<sem::Array>()) {
- return sem::Constant{};
- }
+const sem::Constant* Resolver::EvaluateConstantValue(const ast::CallExpression* call,
+ const sem::Type* ty) {
+ // Note: we are building constant values for array types. The working group as verbally agreed
+ // to support constant expression arrays, but this is not (yet) part of the spec.
+ // See: https://github.com/gpuweb/gpuweb/issues/3056
// For zero value init, return 0s
if (call->args.empty()) {
- return Switch(
- el_ty,
- [&](const sem::AbstractInt*) {
- return sem::Constant(ty, std::vector(result_size, AInt(0)));
- },
- [&](const sem::AbstractFloat*) {
- return sem::Constant(ty, std::vector(result_size, AFloat(0)));
- },
- [&](const sem::I32*) { return sem::Constant(ty, std::vector(result_size, AInt(0))); },
- [&](const sem::U32*) { return sem::Constant(ty, std::vector(result_size, AInt(0))); },
- [&](const sem::F32*) { return sem::Constant(ty, std::vector(result_size, AFloat(0))); },
- [&](const sem::F16*) { return sem::Constant(ty, std::vector(result_size, AFloat(0))); },
- [&](const sem::Bool*) { return sem::Constant(ty, std::vector(result_size, AInt(0))); });
+ return ZeroValue(*builder_, ty);
}
- // Build value for type_ctor from each child value by converting to type_ctor's type.
- std::optional<sem::Constant::Elements> elements;
- for (auto* expr : call->args) {
- auto* arg = builder_->Sem().Get(expr);
+ uint32_t el_count = 0;
+ auto* el_ty = sem::Type::ElementOf(ty, &el_count);
+ if (!el_ty) {
+ return nullptr; // Target type does not support constant values
+ }
+
+ // value_of returns a `const Constant*` for the expression `expr`, or nullptr if the expression
+ // does not have a constant value.
+ auto value_of = [&](const ast::Expression* expr) {
+ return static_cast<const Constant*>(builder_->Sem().Get(expr)->ConstantValue());
+ };
+
+ if (call->args.size() == 1) {
+ // Type constructor or conversion that takes a single argument.
+ auto& src = call->args[0]->source;
+ auto* arg = value_of(call->args[0]);
if (!arg) {
- return sem::Constant{};
- }
- auto value = arg->ConstantValue();
- if (!value) {
- return sem::Constant{};
+ return nullptr; // Single argument is not constant.
}
- // Convert the elements to the desired type.
- auto converted = ConvertElements(value.GetElements(), el_ty);
-
- if (elements.has_value()) {
- // Append the converted vector to elements
- std::visit(
- [&](auto&& dst) {
- using VEC_TY = std::decay_t<decltype(dst)>;
- const auto& src = std::get<VEC_TY>(converted);
- dst.insert(dst.end(), src.begin(), src.end());
- },
- elements.value());
- } else {
- elements = std::move(converted);
+ if (ty->is_scalar()) { // Scalar type conversion: i32(x), u32(x), bool(x), etc
+ return ConvertValue(arg, el_ty, src).Get();
}
+
+ if (arg->Type() == el_ty) {
+ // Argument type matches function type. This is a splat.
+ auto splat = [&](size_t n) { return builder_->create<Splat>(ty, arg, n); };
+ return Switch(
+ ty, //
+ [&](const sem::Vector* v) { return splat(v->Width()); },
+ [&](const sem::Matrix* m) { return splat(m->columns()); },
+ [&](const sem::Array* a) { return splat(a->Count()); });
+ }
+
+ // Argument type and function type mismatch. This is a type conversion.
+ if (auto conv = ConvertValue(arg, ty, src)) {
+ return conv.Get();
+ }
+
+ return nullptr;
}
- // Splat single-value initializers
- std::visit(
- [&](auto&& v) {
- if (v.size() == 1) {
- for (uint32_t i = 0; i < result_size - 1; ++i) {
- v.emplace_back(v[0]);
+ // Multiple arguments. Must be a type constructor.
+
+ std::vector<const Constant*> els; // The constant elements for the composite constant.
+ els.reserve(el_count);
+
+ // Helper for pushing all the argument constants to `els`.
+ auto push_all_args = [&] {
+ for (auto* expr : call->args) {
+ auto* arg = value_of(expr);
+ if (!arg) {
+ return;
+ }
+ els.emplace_back(arg);
+ }
+ };
+
+ Switch(
+ ty, // What's the target type being constructed?
+ [&](const sem::Vector*) {
+ // Vector can be constructed with a mix of scalars / abstract numerics and smaller
+ // vectors.
+ for (auto* expr : call->args) {
+ auto* arg = value_of(expr);
+ if (!arg) {
+ return;
+ }
+ auto* arg_ty = arg->Type();
+ if (auto* arg_vec = arg_ty->As<sem::Vector>()) {
+ // Extract out vector elements.
+ for (uint32_t i = 0; i < arg_vec->Width(); i++) {
+ auto* el = static_cast<const Constant*>(arg->Index(i));
+ if (!el) {
+ return;
+ }
+ els.emplace_back(el);
+ }
+ } else {
+ els.emplace_back(arg);
}
}
},
- elements.value());
+ [&](const sem::Matrix* m) {
+ // Matrix can be constructed with a set of scalars / abstract numerics, or column
+ // vectors.
+ if (call->args.size() == m->columns() * m->rows()) {
+ // Matrix built from scalars / abstract numerics
+ for (uint32_t c = 0; c < m->columns(); c++) {
+ std::vector<const Constant*> column;
+ column.reserve(m->rows());
+ for (uint32_t r = 0; r < m->rows(); r++) {
+ auto* arg = value_of(call->args[r + c * m->rows()]);
+ if (!arg) {
+ return;
+ }
+ column.emplace_back(arg);
+ }
+ els.push_back(CreateComposite(*builder_, m->ColumnType(), std::move(column)));
+ }
+ } else if (call->args.size() == m->columns()) {
+ // Matrix built from column vectors
+ push_all_args();
+ }
+ },
+ [&](const sem::Array*) {
+ // Arrays must be constructed using a list of elements
+ push_all_args();
+ });
- return sem::Constant(ty, std::move(elements.value()));
+ if (els.size() != el_count) {
+ // If the number of constant elements doesn't match the type, then something went wrong.
+ return nullptr;
+ }
+ // Construct and return either a Composite or Splat.
+ return CreateComposite(*builder_, ty, std::move(els));
}
-utils::Result<sem::Constant> Resolver::ConvertValue(const sem::Constant& value,
- const sem::Type* ty,
- const Source& source) {
- if (value.Type() == ty) {
+const sem::Constant* Resolver::EvaluateConstantValue(const ast::IndexAccessorExpression* accessor,
+ const sem::Type*) {
+ auto* obj_sem = builder_->Sem().Get(accessor->object);
+ if (!obj_sem) {
+ return {};
+ }
+
+ auto obj_val = obj_sem->ConstantValue();
+ if (!obj_val) {
+ return {};
+ }
+
+ auto* idx_sem = builder_->Sem().Get(accessor->index);
+ if (!idx_sem) {
+ return {};
+ }
+
+ auto idx_val = idx_sem->ConstantValue();
+ if (!idx_val) {
+ return {};
+ }
+
+ uint32_t el_count = 0;
+ sem::Type::ElementOf(obj_val->Type(), &el_count);
+
+ AInt idx = idx_val->As<AInt>();
+ if (idx < 0 || idx >= el_count) {
+ auto clamped = std::min<AInt::type>(std::max<AInt::type>(idx, 0), el_count - 1);
+ AddWarning("index " + std::to_string(idx) + " out of bounds [0.." +
+ std::to_string(el_count - 1) + "]. Clamping index to " +
+ std::to_string(clamped),
+ accessor->index->source);
+ idx = clamped;
+ }
+
+ return obj_val->Index(static_cast<size_t>(idx));
+}
+
+utils::Result<const sem::Constant*> Resolver::ConvertValue(const sem::Constant* value,
+ const sem::Type* target_ty,
+ const Source& source) {
+ if (value->Type() == target_ty) {
return value;
}
-
- auto* el_ty = sem::Type::ElementOf(ty);
- if (el_ty == nullptr) {
- return sem::Constant{};
+ auto conv = static_cast<const Constant*>(value)->Convert(*builder_, target_ty, source);
+ if (!conv) {
+ return utils::Failure;
}
- if (value.ElementType() == el_ty) {
- return sem::Constant(ty, value.GetElements());
- }
-
- if (auto res = MaterializeElements(value.GetElements(), el_ty, *builder_, source)) {
- return sem::Constant(ty, std::move(res.Get()));
- }
- return utils::Failure;
+ return conv.Get();
}
} // namespace tint::resolver
diff --git a/src/tint/resolver/resolver_constants_test.cc b/src/tint/resolver/resolver_constants_test.cc
index bbdbfea..ff8a189 100644
--- a/src/tint/resolver/resolver_constants_test.cc
+++ b/src/tint/resolver/resolver_constants_test.cc
@@ -14,9 +14,13 @@
#include "src/tint/resolver/resolver.h"
+#include <cmath>
+
#include "gtest/gtest.h"
#include "src/tint/resolver/resolver_test_helper.h"
#include "src/tint/sem/expression.h"
+#include "src/tint/sem/index_accessor_expression.h"
+#include "src/tint/sem/test_helper.h"
using namespace tint::number_suffixes; // NOLINT
@@ -25,6 +29,10 @@
using ResolverConstantsTest = ResolverTest;
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Construction
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
TEST_F(ResolverConstantsTest, Scalar_i32) {
auto* expr = Expr(99_i);
WrapInFunction(expr);
@@ -32,12 +40,13 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
+ ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->Type()->Is<sem::I32>());
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 1u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 99);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->As<AInt>(), 99);
}
TEST_F(ResolverConstantsTest, Scalar_u32) {
@@ -47,12 +56,13 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
+ ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->Type()->Is<sem::U32>());
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 1u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 99u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->As<AInt>(), 99u);
}
TEST_F(ResolverConstantsTest, Scalar_f32) {
@@ -62,12 +72,31 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
+ ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->Type()->Is<sem::F32>());
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 1u);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(0).value, 9.9f);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->As<AFloat>().value, 9.9f);
+}
+
+TEST_F(ResolverConstantsTest, Scalar_f16) {
+ Enable(ast::Extension::kF16);
+ auto* expr = Expr(9.9_h);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ EXPECT_NE(sem, nullptr);
+ EXPECT_TRUE(sem->Type()->Is<sem::F16>());
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+ // 9.9 is not exactly representable by f16, and should be quantized to 9.8984375
+ EXPECT_EQ(sem->ConstantValue()->As<AFloat>(), 9.8984375f);
}
TEST_F(ResolverConstantsTest, Scalar_bool) {
@@ -77,12 +106,13 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
+ ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->Type()->Is<sem::Bool>());
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 1u);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(0), true);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->As<bool>(), true);
}
TEST_F(ResolverConstantsTest, Vec3_ZeroInit_i32) {
@@ -92,16 +122,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 0);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, 0);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, 0);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::I32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), 0);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), 0);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), 0);
}
TEST_F(ResolverConstantsTest, Vec3_ZeroInit_u32) {
@@ -111,16 +155,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::U32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::U32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 0u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, 0u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, 0u);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::U32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), 0u);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), 0u);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), 0u);
}
TEST_F(ResolverConstantsTest, Vec3_ZeroInit_f32) {
@@ -130,16 +188,64 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 0._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 0._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 0._a);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_ZeroInit_f16) {
+ Enable(ast::Extension::kF16);
+ auto* expr = vec3<f16>();
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(0).value, 0.0);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(1).value, 0.0);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(2).value, 0.0);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 0._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 0._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 0._a);
}
TEST_F(ResolverConstantsTest, Vec3_ZeroInit_bool) {
@@ -149,16 +255,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::Bool>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::Bool>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(0), false);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(1), false);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(2), false);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::Bool>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<bool>(), false);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<bool>(), false);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<bool>(), false);
}
TEST_F(ResolverConstantsTest, Vec3_Splat_i32) {
@@ -168,16 +288,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 99);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, 99);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, 99);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::I32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), 99);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), 99);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), 99);
}
TEST_F(ResolverConstantsTest, Vec3_Splat_u32) {
@@ -187,16 +321,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::U32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::U32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 99u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, 99u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, 99u);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::U32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), 99u);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), 99u);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), 99u);
}
TEST_F(ResolverConstantsTest, Vec3_Splat_f32) {
@@ -206,16 +354,65 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 9.9f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 9.9f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 9.9f);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_Splat_f16) {
+ Enable(ast::Extension::kF16);
+ auto* expr = vec3<f16>(9.9_h);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(0).value, 9.9f);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(1).value, 9.9f);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(2).value, 9.9f);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+ // 9.9 is not exactly representable by f16, and should be quantized to 9.8984375
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 9.8984375f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 9.8984375f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 9.8984375f);
}
TEST_F(ResolverConstantsTest, Vec3_Splat_bool) {
@@ -225,16 +422,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::Bool>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::Bool>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(0), true);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(1), true);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(2), true);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::Bool>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<bool>(), true);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<bool>(), true);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<bool>(), true);
}
TEST_F(ResolverConstantsTest, Vec3_FullConstruct_i32) {
@@ -244,16 +455,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 1);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, 2);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, 3);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::I32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), 1);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), 2);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), 3);
}
TEST_F(ResolverConstantsTest, Vec3_FullConstruct_u32) {
@@ -263,16 +488,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::U32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::U32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 1);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, 2);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, 3);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::U32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), 1);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), 2);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), 3);
}
TEST_F(ResolverConstantsTest, Vec3_FullConstruct_f32) {
@@ -282,16 +521,64 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 1.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 2.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 3.f);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_FullConstruct_f16) {
+ Enable(ast::Extension::kF16);
+ auto* expr = vec3<f16>(1_h, 2_h, 3_h);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(0).value, 1.f);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(1).value, 2.f);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(2).value, 3.f);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 1.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 2.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 3.f);
}
TEST_F(ResolverConstantsTest, Vec3_FullConstruct_bool) {
@@ -301,16 +588,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::Bool>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::Bool>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(0), true);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(1), false);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(2), true);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::Bool>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<bool>(), true);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<bool>(), false);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<bool>(), true);
}
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_i32) {
@@ -320,16 +621,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 1);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, 2);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, 3);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::I32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), 1);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), 2);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), 3);
}
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_u32) {
@@ -339,16 +654,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::U32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::U32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 1);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, 2);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, 3);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::U32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), 1);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), 2);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), 3);
}
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f32) {
@@ -358,16 +687,332 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 1.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 2.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 3.f);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f32_all_10) {
+ auto* expr = vec3<f32>(10_f, vec2<f32>(10_f, 10_f));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(0).value, 1.f);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(1).value, 2.f);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(2).value, 3.f);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 10_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), 10_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), 10_f);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f32_all_positive_0) {
+ auto* expr = vec3<f32>(0_f, vec2<f32>(0_f, 0_f));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ EXPECT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), 0_f);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f32_all_negative_0) {
+ auto* expr = vec3<f32>(vec2<f32>(-0_f, -0_f), -0_f);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ EXPECT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), -0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), -0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), -0_f);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f32_mixed_sign_0) {
+ auto* expr = vec3<f32>(0_f, vec2<f32>(-0_f, 0_f));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ EXPECT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), -0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), 0_f);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16) {
+ Enable(ast::Extension::kF16);
+ auto* expr = vec3<f16>(1_h, vec2<f16>(2_h, 3_h));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ EXPECT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 1.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 2.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 3.f);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_all_10) {
+ Enable(ast::Extension::kF16);
+ auto* expr = vec3<f16>(10_h, vec2<f16>(10_h, 10_h));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ EXPECT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f16>(), 10_h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f16>(), 10_h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f16>(), 10_h);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_all_positive_0) {
+ Enable(ast::Extension::kF16);
+ auto* expr = vec3<f16>(0_h, vec2<f16>(0_h, 0_h));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ EXPECT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f16>(), 0_h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f16>(), 0_h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f16>(), 0_h);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_all_negative_0) {
+ Enable(ast::Extension::kF16);
+ auto* expr = vec3<f16>(vec2<f16>(-0_h, -0_h), -0_h);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ EXPECT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f16>(), -0_h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f16>(), -0_h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f16>(), -0_h);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_mixed_sign_0) {
+ Enable(ast::Extension::kF16);
+ auto* expr = vec3<f16>(0_h, vec2<f16>(-0_h, 0_h));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ EXPECT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f16>(), 0_h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f16>(), -0_h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f16>(), 0_h);
}
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_bool) {
@@ -377,16 +1022,96 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::Bool>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::Bool>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(0), true);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(1), false);
- EXPECT_EQ(sem->ConstantValue().Element<bool>(2), true);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::Bool>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<bool>(), true);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<bool>(), false);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<bool>(), true);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_all_true) {
+ auto* expr = vec3<bool>(true, vec2<bool>(true, true));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::Bool>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<bool>(), true);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<bool>(), true);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<bool>(), true);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_MixConstruct_all_false) {
+ auto* expr = vec3<bool>(false, vec2<bool>(false, false));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::Bool>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<bool>(), false);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<bool>(), false);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<bool>(), false);
}
TEST_F(ResolverConstantsTest, Vec3_Convert_f32_to_i32) {
@@ -396,16 +1121,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 1);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, 2);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, 3);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::I32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), 1);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), 2);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), 3);
}
TEST_F(ResolverConstantsTest, Vec3_Convert_u32_to_f32) {
@@ -415,16 +1154,98 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 10.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 20.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 30.f);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_Convert_f16_to_i32) {
+ Enable(ast::Extension::kF16);
+ auto* expr = vec3<i32>(vec3<f16>(1.1_h, 2.2_h, 3.3_h));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(0).value, 10.f);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(1).value, 20.f);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(2).value, 30.f);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::I32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), 1_i);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), 2_i);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), 3_i);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_Convert_u32_to_f16) {
+ Enable(ast::Extension::kF16);
+ auto* expr = vec3<f16>(vec3<u32>(10_u, 20_u, 30_u));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ EXPECT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 10.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), 20.f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 30.f);
}
TEST_F(ResolverConstantsTest, Vec3_Convert_Large_f32_to_i32) {
@@ -434,16 +1255,30 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, i32::kHighest);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, i32::kLowest);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, i32::kHighest);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::I32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), i32::kHighest);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), i32::kLowest);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), i32::kHighest);
}
TEST_F(ResolverConstantsTest, Vec3_Convert_Large_f32_to_u32) {
@@ -453,23 +1288,36 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::U32>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::U32>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, u32::kHighest);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(1).value, u32::kLowest);
- EXPECT_EQ(sem->ConstantValue().Element<AInt>(2).value, u32::kHighest);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::U32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), u32::kHighest);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), u32::kLowest);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), u32::kHighest);
}
-// TODO(crbug.com/tint/1502): Enable when f16 overloads are implemented
-TEST_F(ResolverConstantsTest, DISABLED_Vec3_Convert_Large_f32_to_f16) {
+TEST_F(ResolverConstantsTest, Vec3_Convert_Large_f32_to_f16) {
Enable(ast::Extension::kF16);
- auto* expr = vec3<f16>(vec3<f32>(0.00001_f, -0.00002_f, 0.00003_f));
+ auto* expr = vec3<f16>(vec3<f32>(1e10_f, -1e20_f, 1e30_f));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -477,38 +1325,923 @@
constexpr auto kInf = std::numeric_limits<double>::infinity();
auto* sem = Sem().Get(expr);
- EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::F16>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F16>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(0).value, kInf);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(1).value, -kInf);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(2).value, kInf);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), kInf);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), -kInf);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), kInf);
}
-// TODO(crbug.com/tint/1502): Enable when f16 overloads are implemented
-TEST_F(ResolverConstantsTest, DISABLED_Vec3_Convert_Small_f32_to_f16) {
+TEST_F(ResolverConstantsTest, Vec3_Convert_Small_f32_to_f16) {
Enable(ast::Extension::kF16);
- auto* expr = vec3<f16>(vec3<f32>(1e-10_f, -1e20_f, 1e30_f));
+ auto* expr = vec3<f16>(vec3<f32>(1e-20_f, -2e-30_f, 3e-40_f));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F16>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), 0.0);
+ EXPECT_FALSE(std::signbit(sem->ConstantValue()->Index(0)->As<AFloat>().value));
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), -0.0);
+ EXPECT_TRUE(std::signbit(sem->ConstantValue()->Index(1)->As<AFloat>().value));
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), 0.0);
+ EXPECT_FALSE(std::signbit(sem->ConstantValue()->Index(2)->As<AFloat>().value));
+}
+
+TEST_F(ResolverConstantsTest, Mat2x3_ZeroInit_f32) {
+ auto* expr = mat2x3<f32>();
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* mat = sem->Type()->As<sem::Matrix>();
+ ASSERT_NE(mat, nullptr);
+ EXPECT_TRUE(mat->type()->Is<sem::F32>());
+ EXPECT_EQ(mat->columns(), 2u);
+ EXPECT_EQ(mat->rows(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<f32>(), 0._f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<f32>(), 0._f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(2)->As<f32>(), 0._f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<f32>(), 0._f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<f32>(), 0._f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<f32>(), 0._f);
+}
+
+TEST_F(ResolverConstantsTest, Mat2x3_ZeroInit_f16) {
+ Enable(ast::Extension::kF16);
+
+ auto* expr = mat2x3<f16>();
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
EXPECT_NE(sem, nullptr);
- ASSERT_TRUE(sem->Type()->Is<sem::Vector>());
- EXPECT_TRUE(sem->Type()->As<sem::Vector>()->type()->Is<sem::F16>());
- EXPECT_EQ(sem->Type()->As<sem::Vector>()->Width(), 3u);
- EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
- EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F16>());
- ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(0).value, 0.0);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(1).value, -0.0);
- EXPECT_EQ(sem->ConstantValue().Element<AFloat>(2).value, 0.0);
+ auto* mat = sem->Type()->As<sem::Matrix>();
+ ASSERT_NE(mat, nullptr);
+ EXPECT_TRUE(mat->type()->Is<sem::F16>());
+ EXPECT_EQ(mat->columns(), 2u);
+ EXPECT_EQ(mat->rows(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<f16>(), 0._h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<f16>(), 0._h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(2)->As<f16>(), 0._h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<f16>(), 0._h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<f16>(), 0._h);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<f16>(), 0._h);
+}
+
+TEST_F(ResolverConstantsTest, Mat3x2_Construct_Scalars_af) {
+ auto* expr = Construct(ty.mat(nullptr, 3, 2), 1.0_a, 2.0_a, 3.0_a, 4.0_a, 5.0_a, 6.0_a);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* mat = sem->Type()->As<sem::Matrix>();
+ ASSERT_NE(mat, nullptr);
+ EXPECT_TRUE(mat->type()->Is<sem::F32>());
+ EXPECT_EQ(mat->columns(), 3u);
+ EXPECT_EQ(mat->rows(), 2u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<AFloat>(), 1._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<AFloat>(), 2._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<AFloat>(), 3._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<AFloat>(), 4._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(0)->As<AFloat>(), 5._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(1)->As<AFloat>(), 6._a);
+}
+
+TEST_F(ResolverConstantsTest, Mat3x2_Construct_Columns_af) {
+ auto* expr = Construct(ty.mat(nullptr, 3, 2), //
+ vec(nullptr, 2u, 1.0_a, 2.0_a), //
+ vec(nullptr, 2u, 3.0_a, 4.0_a), //
+ vec(nullptr, 2u, 5.0_a, 6.0_a));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* mat = sem->Type()->As<sem::Matrix>();
+ ASSERT_NE(mat, nullptr);
+ EXPECT_TRUE(mat->type()->Is<sem::F32>());
+ EXPECT_EQ(mat->columns(), 3u);
+ EXPECT_EQ(mat->rows(), 2u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<AFloat>(), 1._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<AFloat>(), 2._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<AFloat>(), 3._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<AFloat>(), 4._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(0)->As<AFloat>(), 5._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(1)->As<AFloat>(), 6._a);
+}
+
+TEST_F(ResolverConstantsTest, Array_i32_Zero) {
+ auto* expr = Construct(ty.array<i32, 4>());
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* arr = sem->Type()->As<sem::Array>();
+ ASSERT_NE(arr, nullptr);
+ EXPECT_TRUE(arr->ElemType()->Is<sem::I32>());
+ EXPECT_EQ(arr->Count(), 4u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<i32>(), 0_i);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<i32>(), 0_i);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<i32>(), 0_i);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(3)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(3)->As<i32>(), 0_i);
+}
+
+TEST_F(ResolverConstantsTest, Array_f32_Zero) {
+ auto* expr = Construct(ty.array<f32, 4>());
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* arr = sem->Type()->As<sem::Array>();
+ ASSERT_NE(arr, nullptr);
+ EXPECT_TRUE(arr->ElemType()->Is<sem::F32>());
+ EXPECT_EQ(arr->Count(), 4u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(3)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(3)->As<f32>(), 0_f);
+}
+
+TEST_F(ResolverConstantsTest, Array_vec3_f32_Zero) {
+ auto* expr = Construct(ty.array(ty.vec3<f32>(), 2_u));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* arr = sem->Type()->As<sem::Array>();
+ ASSERT_NE(arr, nullptr);
+ EXPECT_TRUE(arr->ElemType()->Is<sem::Vector>());
+ EXPECT_EQ(arr->Count(), 2u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(2)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(2)->AllEqual());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(2)->AnyZero());
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<f32>(), 0_f);
+}
+
+TEST_F(ResolverConstantsTest, Array_i32_Elements) {
+ auto* expr = Construct(ty.array<i32, 4>(), 10_i, 20_i, 30_i, 40_i);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* arr = sem->Type()->As<sem::Array>();
+ ASSERT_NE(arr, nullptr);
+ EXPECT_TRUE(arr->ElemType()->Is<sem::I32>());
+ EXPECT_EQ(arr->Count(), 4u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<i32>(), 10_i);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<i32>(), 20_i);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<i32>(), 30_i);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(3)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(3)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(3)->As<i32>(), 40_i);
+}
+
+TEST_F(ResolverConstantsTest, Array_f32_Elements) {
+ auto* expr = Construct(ty.array<f32, 4>(), 10_f, 20_f, 30_f, 40_f);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* arr = sem->Type()->As<sem::Array>();
+ ASSERT_NE(arr, nullptr);
+ EXPECT_TRUE(arr->ElemType()->Is<sem::F32>());
+ EXPECT_EQ(arr->Count(), 4u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 10_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), 20_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), 30_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(3)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(3)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(3)->As<f32>(), 40_f);
+}
+
+TEST_F(ResolverConstantsTest, Array_vec3_f32_Elements) {
+ auto* expr = Construct(ty.array(ty.vec3<f32>(), 2_u), //
+ vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* arr = sem->Type()->As<sem::Array>();
+ ASSERT_NE(arr, nullptr);
+ EXPECT_TRUE(arr->ElemType()->Is<sem::Vector>());
+ EXPECT_EQ(arr->Count(), 2u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<f32>(), 1_f);
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<f32>(), 2_f);
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(2)->As<f32>(), 3_f);
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<f32>(), 4_f);
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<f32>(), 5_f);
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<f32>(), 6_f);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Indexing
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TEST_F(ResolverConstantsTest, Vec3_Index) {
+ auto* expr = IndexAccessor(vec3<i32>(1_i, 2_i, 3_i), 2_i);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ ASSERT_TRUE(sem->Type()->Is<sem::I32>());
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->As<i32>(), 3_i);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_Index_OOB_High) {
+ auto* expr = IndexAccessor(vec3<i32>(1_i, 2_i, 3_i), Expr(Source{{12, 34}}, 3_i));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ EXPECT_EQ(r()->error(), "12:34 warning: index 3 out of bounds [0..2]. Clamping index to 2");
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ ASSERT_TRUE(sem->Type()->Is<sem::I32>());
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->As<i32>(), 3_i);
+}
+
+TEST_F(ResolverConstantsTest, Vec3_Index_OOB_Low) {
+ auto* expr = IndexAccessor(vec3<i32>(1_i, 2_i, 3_i), Expr(Source{{12, 34}}, -3_i));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ EXPECT_EQ(r()->error(), "12:34 warning: index -3 out of bounds [0..2]. Clamping index to 0");
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ ASSERT_TRUE(sem->Type()->Is<sem::I32>());
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_TRUE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->As<i32>(), 1_i);
+}
+
+TEST_F(ResolverConstantsTest, Mat3x2_Index) {
+ auto* expr = IndexAccessor(
+ mat3x2<f32>(vec2<f32>(1._a, 2._a), vec2<f32>(3._a, 4._a), vec2<f32>(5._a, 6._a)), 2_i);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_EQ(vec->Width(), 2u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 5._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), 6._a);
+}
+
+TEST_F(ResolverConstantsTest, Mat3x2_Index_OOB_High) {
+ auto* expr = IndexAccessor(
+ mat3x2<f32>(vec2<f32>(1._a, 2._a), vec2<f32>(3._a, 4._a), vec2<f32>(5._a, 6._a)),
+ Expr(Source{{12, 34}}, 3_i));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ EXPECT_EQ(r()->error(), "12:34 warning: index 3 out of bounds [0..2]. Clamping index to 2");
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_EQ(vec->Width(), 2u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 5._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), 6._a);
+}
+
+TEST_F(ResolverConstantsTest, Mat3x2_Index_OOB_Low) {
+ auto* expr = IndexAccessor(
+ mat3x2<f32>(vec2<f32>(1._a, 2._a), vec2<f32>(3._a, 4._a), vec2<f32>(5._a, 6._a)),
+ Expr(Source{{12, 34}}, -3_i));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ EXPECT_EQ(r()->error(), "12:34 warning: index -3 out of bounds [0..2]. Clamping index to 0");
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_EQ(vec->Width(), 2u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 1._a);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), 2._a);
+}
+
+TEST_F(ResolverConstantsTest, Array_vec3_f32_Index) {
+ auto* expr = IndexAccessor(Construct(ty.array(ty.vec3<f32>(), 2_u), //
+ vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
+ 1_i);
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 4_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), 5_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), 6_f);
+}
+
+TEST_F(ResolverConstantsTest, Array_vec3_f32_Index_OOB_High) {
+ auto* expr = IndexAccessor(Construct(ty.array(ty.vec3<f32>(), 2_u), //
+ vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
+ Expr(Source{{12, 34}}, 2_i));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ EXPECT_EQ(r()->error(), "12:34 warning: index 2 out of bounds [0..1]. Clamping index to 1");
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 4_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), 5_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), 6_f);
+}
+
+TEST_F(ResolverConstantsTest, Array_vec3_f32_Index_OOB_Low) {
+ auto* expr = IndexAccessor(Construct(ty.array(ty.vec3<f32>(), 2_u), //
+ vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
+ Expr(Source{{12, 34}}, -2_i));
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ EXPECT_EQ(r()->error(), "12:34 warning: index -2 out of bounds [0..1]. Clamping index to 0");
+
+ auto* sem = Sem().Get(expr);
+ ASSERT_NE(sem, nullptr);
+ auto* vec = sem->Type()->As<sem::Vector>();
+ ASSERT_NE(vec, nullptr);
+ EXPECT_TRUE(vec->type()->Is<sem::F32>());
+ EXPECT_EQ(vec->Width(), 3u);
+ EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
+ EXPECT_FALSE(sem->ConstantValue()->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(0)->As<f32>(), 1_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(1)->As<f32>(), 2_f);
+
+ EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), 3_f);
+}
+
+TEST_F(ResolverConstantsTest, ChainedIndex) {
+ auto* arr_expr = Construct(ty.array(ty.mat2x3<f32>(), 2_u), // array<mat2x3<f32>, 2u>
+ mat2x3<f32>(vec3<f32>(1_f, 2_f, 3_f), //
+ vec3<f32>(4_f, 5_f, 6_f)), //
+ mat2x3<f32>(vec3<f32>(7_f, 0_f, 9_f), //
+ vec3<f32>(10_f, 11_f, 12_f)));
+
+ auto* mat_expr = IndexAccessor(arr_expr, 1_i); // arr[1]
+ auto* vec_expr = IndexAccessor(mat_expr, 0_i); // arr[1][0]
+ auto* f32_expr = IndexAccessor(vec_expr, 2_i); // arr[1][0][2]
+ WrapInFunction(f32_expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ {
+ auto* mat = Sem().Get(mat_expr);
+ EXPECT_NE(mat, nullptr);
+ auto* ty = mat->Type()->As<sem::Matrix>();
+ ASSERT_NE(mat->Type(), nullptr);
+ EXPECT_TRUE(ty->ColumnType()->Is<sem::Vector>());
+ EXPECT_EQ(ty->columns(), 2u);
+ EXPECT_EQ(ty->rows(), 3u);
+ EXPECT_EQ(mat->ConstantValue()->Type(), mat->Type());
+ EXPECT_FALSE(mat->ConstantValue()->AllEqual());
+ EXPECT_TRUE(mat->ConstantValue()->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(0)->Index(0)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(0)->Index(0)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(0)->Index(0)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(0)->Index(0)->As<f32>(), 7_f);
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(0)->Index(1)->AllEqual());
+ EXPECT_TRUE(mat->ConstantValue()->Index(0)->Index(1)->AnyZero());
+ EXPECT_TRUE(mat->ConstantValue()->Index(0)->Index(1)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(0)->Index(1)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(0)->Index(2)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(0)->Index(2)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(0)->Index(2)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(0)->Index(2)->As<f32>(), 9_f);
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(1)->Index(0)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(0)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(0)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(1)->Index(0)->As<f32>(), 10_f);
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(1)->Index(1)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(1)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(1)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(1)->Index(1)->As<f32>(), 11_f);
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(1)->Index(2)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(2)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(2)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(1)->Index(2)->As<f32>(), 12_f);
+ }
+ {
+ auto* vec = Sem().Get(vec_expr);
+ EXPECT_NE(vec, nullptr);
+ auto* ty = vec->Type()->As<sem::Vector>();
+ ASSERT_NE(vec->Type(), nullptr);
+ EXPECT_TRUE(ty->type()->Is<sem::F32>());
+ EXPECT_EQ(ty->Width(), 3u);
+ EXPECT_EQ(vec->ConstantValue()->Type(), vec->Type());
+ EXPECT_FALSE(vec->ConstantValue()->AllEqual());
+ EXPECT_TRUE(vec->ConstantValue()->AnyZero());
+ EXPECT_FALSE(vec->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(vec->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(vec->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(vec->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(vec->ConstantValue()->Index(0)->As<f32>(), 7_f);
+
+ EXPECT_TRUE(vec->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_TRUE(vec->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_TRUE(vec->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(vec->ConstantValue()->Index(1)->As<f32>(), 0_f);
+
+ EXPECT_TRUE(vec->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(vec->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(vec->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(vec->ConstantValue()->Index(2)->As<f32>(), 9_f);
+ }
+ {
+ auto* f = Sem().Get(f32_expr);
+ EXPECT_NE(f, nullptr);
+ EXPECT_TRUE(f->Type()->Is<sem::F32>());
+ EXPECT_EQ(f->ConstantValue()->Type(), f->Type());
+ EXPECT_TRUE(f->ConstantValue()->AllEqual());
+ EXPECT_FALSE(f->ConstantValue()->AnyZero());
+ EXPECT_FALSE(f->ConstantValue()->AllZero());
+ EXPECT_EQ(f->ConstantValue()->As<f32>(), 9_f);
+ }
+}
+
+TEST_F(ResolverConstantsTest, ChainedIndex_OOB) {
+ auto* arr_expr = Construct(ty.array(ty.mat2x3<f32>(), 2_u), // array<mat2x3<f32>, 2u>
+ mat2x3<f32>(vec3<f32>(1_f, 2_f, 3_f), //
+ vec3<f32>(4_f, 5_f, 6_f)), //
+ mat2x3<f32>(vec3<f32>(7_f, 8_f, 9_f), //
+ vec3<f32>(10_f, 11_f, 12_f)));
+
+ auto* mat_expr = IndexAccessor(arr_expr, Expr(Source{{1, 2}}, -3_i)); // arr[3]
+ auto* vec_expr = IndexAccessor(mat_expr, Expr(Source{{3, 4}}, -2_i)); // arr[3][-2]
+ auto* f32_expr = IndexAccessor(vec_expr, Expr(Source{{5, 6}}, 4_i)); // arr[3][-2][4]
+ WrapInFunction(f32_expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ EXPECT_EQ(r()->error(), R"(1:2 warning: index -3 out of bounds [0..1]. Clamping index to 0
+3:4 warning: index -2 out of bounds [0..1]. Clamping index to 0
+5:6 warning: index 4 out of bounds [0..2]. Clamping index to 2)");
+
+ {
+ auto* mat = Sem().Get(mat_expr);
+ EXPECT_NE(mat, nullptr);
+ auto* ty = mat->Type()->As<sem::Matrix>();
+ ASSERT_NE(mat->Type(), nullptr);
+ EXPECT_TRUE(ty->ColumnType()->Is<sem::Vector>());
+ EXPECT_EQ(ty->columns(), 2u);
+ EXPECT_EQ(ty->rows(), 3u);
+ EXPECT_EQ(mat->ConstantValue()->Type(), mat->Type());
+ EXPECT_FALSE(mat->ConstantValue()->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(0)->Index(0)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(0)->Index(0)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(0)->Index(0)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(0)->Index(0)->As<f32>(), 1_f);
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(0)->Index(1)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(0)->Index(1)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(0)->Index(1)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(0)->Index(1)->As<f32>(), 2_f);
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(0)->Index(2)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(0)->Index(2)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(0)->Index(2)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(0)->Index(2)->As<f32>(), 3_f);
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(1)->Index(0)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(0)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(0)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(1)->Index(0)->As<f32>(), 4_f);
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(1)->Index(1)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(1)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(1)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(1)->Index(1)->As<f32>(), 5_f);
+
+ EXPECT_TRUE(mat->ConstantValue()->Index(1)->Index(2)->AllEqual());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(2)->AnyZero());
+ EXPECT_FALSE(mat->ConstantValue()->Index(1)->Index(2)->AllZero());
+ EXPECT_EQ(mat->ConstantValue()->Index(1)->Index(2)->As<f32>(), 6_f);
+ }
+ {
+ auto* vec = Sem().Get(vec_expr);
+ EXPECT_NE(vec, nullptr);
+ auto* ty = vec->Type()->As<sem::Vector>();
+ ASSERT_NE(vec->Type(), nullptr);
+ EXPECT_TRUE(ty->type()->Is<sem::F32>());
+ EXPECT_EQ(ty->Width(), 3u);
+ EXPECT_EQ(vec->ConstantValue()->Type(), vec->Type());
+ EXPECT_FALSE(vec->ConstantValue()->AllEqual());
+ EXPECT_FALSE(vec->ConstantValue()->AnyZero());
+ EXPECT_FALSE(vec->ConstantValue()->AllZero());
+
+ EXPECT_TRUE(vec->ConstantValue()->Index(0)->AllEqual());
+ EXPECT_FALSE(vec->ConstantValue()->Index(0)->AnyZero());
+ EXPECT_FALSE(vec->ConstantValue()->Index(0)->AllZero());
+ EXPECT_EQ(vec->ConstantValue()->Index(0)->As<f32>(), 1_f);
+
+ EXPECT_TRUE(vec->ConstantValue()->Index(1)->AllEqual());
+ EXPECT_FALSE(vec->ConstantValue()->Index(1)->AnyZero());
+ EXPECT_FALSE(vec->ConstantValue()->Index(1)->AllZero());
+ EXPECT_EQ(vec->ConstantValue()->Index(1)->As<f32>(), 2_f);
+
+ EXPECT_TRUE(vec->ConstantValue()->Index(2)->AllEqual());
+ EXPECT_FALSE(vec->ConstantValue()->Index(2)->AnyZero());
+ EXPECT_FALSE(vec->ConstantValue()->Index(2)->AllZero());
+ EXPECT_EQ(vec->ConstantValue()->Index(2)->As<f32>(), 3_f);
+ }
+ {
+ auto* f = Sem().Get(f32_expr);
+ EXPECT_NE(f, nullptr);
+ EXPECT_TRUE(f->Type()->Is<sem::F32>());
+ EXPECT_EQ(f->ConstantValue()->Type(), f->Type());
+ EXPECT_TRUE(f->ConstantValue()->AllEqual());
+ EXPECT_FALSE(f->ConstantValue()->AnyZero());
+ EXPECT_FALSE(f->ConstantValue()->AllZero());
+ EXPECT_EQ(f->ConstantValue()->As<f32>(), 3_f);
+ }
}
} // namespace
diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc
index 0fecf0c..9b56c31 100644
--- a/src/tint/resolver/resolver_test.cc
+++ b/src/tint/resolver/resolver_test.cc
@@ -316,7 +316,7 @@
TEST_F(ResolverTest, Stmt_VariableDecl_ModuleScope) {
auto* init = Expr(2_i);
- Global("my_var", ty.i32(), ast::StorageClass::kPrivate, init);
+ GlobalVar("my_var", ty.i32(), ast::StorageClass::kPrivate, init);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -424,7 +424,7 @@
TEST_F(ResolverTest, ArraySize_UnsignedLiteral) {
// var<private> a : array<f32, 10u>;
- auto* a = Global("a", ty.array(ty.f32(), Expr(10_u)), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.array(ty.f32(), Expr(10_u)), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -437,7 +437,7 @@
TEST_F(ResolverTest, ArraySize_SignedLiteral) {
// var<private> a : array<f32, 10i>;
- auto* a = Global("a", ty.array(ty.f32(), Expr(10_i)), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.array(ty.f32(), Expr(10_i)), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -448,11 +448,11 @@
EXPECT_EQ(ary->Count(), 10u);
}
-TEST_F(ResolverTest, ArraySize_UnsignedConstant) {
- // let size = 0u;
+TEST_F(ResolverTest, ArraySize_UnsignedConst) {
+ // const size = 10u;
// var<private> a : array<f32, size>;
GlobalConst("size", nullptr, Expr(10_u));
- auto* a = Global("a", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -463,11 +463,11 @@
EXPECT_EQ(ary->Count(), 10u);
}
-TEST_F(ResolverTest, ArraySize_SignedConstant) {
- // let size = 0;
+TEST_F(ResolverTest, ArraySize_SignedConst) {
+ // const size = 0;
// var<private> a : array<f32, size>;
GlobalConst("size", nullptr, Expr(10_i));
- auto* a = Global("a", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -479,7 +479,7 @@
}
TEST_F(ResolverTest, Expr_Bitcast) {
- Global("name", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("name", ty.f32(), ast::StorageClass::kPrivate);
auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr("name"));
WrapInFunction(bitcast);
@@ -542,7 +542,7 @@
}
TEST_F(ResolverTest, Expr_Cast) {
- Global("name", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("name", ty.f32(), ast::StorageClass::kPrivate);
auto* cast = Construct(ty.f32(), "name");
WrapInFunction(cast);
@@ -600,7 +600,7 @@
}
TEST_F(ResolverTest, Expr_Identifier_GlobalVariable) {
- auto* my_var = Global("my_var", ty.f32(), ast::StorageClass::kPrivate);
+ auto* my_var = GlobalVar("my_var", ty.f32(), ast::StorageClass::kPrivate);
auto* ident = Expr("my_var");
WrapInFunction(ident);
@@ -615,7 +615,7 @@
EXPECT_EQ(VarOf(ident)->Declaration(), my_var);
}
-TEST_F(ResolverTest, Expr_Identifier_GlobalConstant) {
+TEST_F(ResolverTest, Expr_Identifier_GlobalConst) {
auto* my_var = GlobalConst("my_var", ty.f32(), Construct(ty.f32()));
auto* ident = Expr("my_var");
@@ -776,13 +776,14 @@
TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
auto* s = Structure("S", {Member("m", ty.u32())});
- auto* sb_var = Global("sb_var", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
- auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
- auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
+ auto* sb_var =
+ GlobalVar("sb_var", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
+ auto* wg_var = GlobalVar("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
+ auto* priv_var = GlobalVar("priv_var", ty.f32(), ast::StorageClass::kPrivate);
auto* func = Func("my_func", {}, ty.void_(),
{
@@ -808,13 +809,14 @@
TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
auto* s = Structure("S", {Member("m", ty.u32())});
- auto* sb_var = Global("sb_var", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
- auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
- auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
+ auto* sb_var =
+ GlobalVar("sb_var", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
+ auto* wg_var = GlobalVar("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
+ auto* priv_var = GlobalVar("priv_var", ty.f32(), ast::StorageClass::kPrivate);
Func("my_func", {}, ty.f32(),
{Assign("wg_var", "wg_var"), Assign("sb_var", "sb_var"), Assign("priv_var", "priv_var"),
@@ -945,10 +947,10 @@
EXPECT_EQ(func_sem->WorkgroupSize()[2].overridable_const, nullptr);
}
-TEST_F(ResolverTest, Function_WorkgroupSize_Consts) {
- // let width = 16i;
- // let height = 8i;
- // let depth = 2i;
+TEST_F(ResolverTest, Function_WorkgroupSize_ViaConst) {
+ // const width = 16i;
+ // const height = 8i;
+ // const depth = 2i;
// @compute @workgroup_size(width, height, depth)
// fn main() {}
GlobalConst("width", ty.i32(), Expr(16_i));
@@ -973,9 +975,9 @@
EXPECT_EQ(func_sem->WorkgroupSize()[2].overridable_const, nullptr);
}
-TEST_F(ResolverTest, Function_WorkgroupSize_Consts_NestedInitializer) {
- // let width = i32(i32(i32(8i)));
- // let height = i32(i32(i32(4i)));
+TEST_F(ResolverTest, Function_WorkgroupSize_ViaConst_NestedInitializer) {
+ // const width = i32(i32(i32(8i)));
+ // const height = i32(i32(i32(4i)));
// @compute @workgroup_size(width, height)
// fn main() {}
GlobalConst("width", ty.i32(),
@@ -1059,7 +1061,7 @@
TEST_F(ResolverTest, Function_WorkgroupSize_Mixed) {
// @id(1) override height = 2i;
- // let depth = 3i;
+ // const depth = 3i;
// @compute @workgroup_size(8, height, depth)
// fn main() {}
auto* height = Override("height", ty.i32(), Expr(2_i), {Id(0)});
@@ -1086,7 +1088,7 @@
TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
auto* st =
Structure("S", {Member("first_member", ty.i32()), Member("second_member", ty.f32())});
- Global("my_struct", ty.Of(st), ast::StorageClass::kPrivate);
+ GlobalVar("my_struct", ty.Of(st), ast::StorageClass::kPrivate);
auto* mem = MemberAccessor("my_struct", "second_member");
WrapInFunction(mem);
@@ -1101,6 +1103,7 @@
auto* sma = Sem().Get(mem)->As<sem::StructMemberAccess>();
ASSERT_NE(sma, nullptr);
EXPECT_TRUE(sma->Member()->Type()->Is<sem::F32>());
+ EXPECT_EQ(sma->Object()->Declaration(), mem->structure);
EXPECT_EQ(sma->Member()->Index(), 1u);
EXPECT_EQ(sma->Member()->Declaration()->symbol, Symbols().Get("second_member"));
}
@@ -1109,7 +1112,7 @@
auto* st =
Structure("S", {Member("first_member", ty.i32()), Member("second_member", ty.f32())});
auto* alias = Alias("alias", ty.Of(st));
- Global("my_struct", ty.Of(alias), ast::StorageClass::kPrivate);
+ GlobalVar("my_struct", ty.Of(alias), ast::StorageClass::kPrivate);
auto* mem = MemberAccessor("my_struct", "second_member");
WrapInFunction(mem);
@@ -1123,12 +1126,13 @@
EXPECT_TRUE(ref->StoreType()->Is<sem::F32>());
auto* sma = Sem().Get(mem)->As<sem::StructMemberAccess>();
ASSERT_NE(sma, nullptr);
+ EXPECT_EQ(sma->Object()->Declaration(), mem->structure);
EXPECT_TRUE(sma->Member()->Type()->Is<sem::F32>());
EXPECT_EQ(sma->Member()->Index(), 1u);
}
TEST_F(ResolverTest, Expr_MemberAccessor_VectorSwizzle) {
- Global("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* mem = MemberAccessor("my_vec", "xzyw");
WrapInFunction(mem);
@@ -1139,12 +1143,14 @@
ASSERT_TRUE(TypeOf(mem)->Is<sem::Vector>());
EXPECT_TRUE(TypeOf(mem)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(mem)->As<sem::Vector>()->Width(), 4u);
- ASSERT_TRUE(Sem().Get(mem)->Is<sem::Swizzle>());
- EXPECT_THAT(Sem().Get(mem)->As<sem::Swizzle>()->Indices(), ElementsAre(0, 2, 1, 3));
+ auto* sma = Sem().Get(mem)->As<sem::Swizzle>();
+ ASSERT_NE(sma, nullptr);
+ EXPECT_EQ(sma->Object()->Declaration(), mem->structure);
+ EXPECT_THAT(sma->As<sem::Swizzle>()->Indices(), ElementsAre(0, 2, 1, 3));
}
TEST_F(ResolverTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
- Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_vec", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* mem = MemberAccessor("my_vec", "b");
WrapInFunction(mem);
@@ -1156,7 +1162,9 @@
auto* ref = TypeOf(mem)->As<sem::Reference>();
ASSERT_TRUE(ref->StoreType()->Is<sem::F32>());
- ASSERT_TRUE(Sem().Get(mem)->Is<sem::Swizzle>());
+ auto* sma = Sem().Get(mem)->As<sem::Swizzle>();
+ ASSERT_NE(sma, nullptr);
+ EXPECT_EQ(sma->Object()->Declaration(), mem->structure);
EXPECT_THAT(Sem().Get(mem)->As<sem::Swizzle>()->Indices(), ElementsAre(2));
}
@@ -1178,7 +1186,7 @@
auto* stB = Structure("B", {Member("foo", ty.vec4<f32>())});
auto* stA = Structure("A", {Member("mem", ty.array(ty.Of(stB), 3_i))});
- Global("c", ty.Of(stA), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.Of(stA), ast::StorageClass::kPrivate);
auto* mem =
MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0_i), "foo"), "yx");
@@ -1196,7 +1204,7 @@
TEST_F(ResolverTest, Expr_MemberAccessor_InBinaryOp) {
auto* st =
Structure("S", {Member("first_member", ty.f32()), Member("second_member", ty.f32())});
- Global("my_struct", ty.Of(st), ast::StorageClass::kPrivate);
+ GlobalVar("my_struct", ty.Of(st), ast::StorageClass::kPrivate);
auto* expr = Add(MemberAccessor("my_struct", "first_member"),
MemberAccessor("my_struct", "second_member"));
@@ -1499,8 +1507,8 @@
ss << FriendlyName(lhs_type) << " " << params.op << " " << FriendlyName(rhs_type);
SCOPED_TRACE(ss.str());
- Global("lhs", lhs_type, ast::StorageClass::kPrivate);
- Global("rhs", rhs_type, ast::StorageClass::kPrivate);
+ GlobalVar("lhs", lhs_type, ast::StorageClass::kPrivate);
+ GlobalVar("rhs", rhs_type, ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(params.op, Expr("lhs"), Expr("rhs"));
WrapInFunction(expr);
@@ -1534,8 +1542,8 @@
<< FriendlyName(rhs_type);
SCOPED_TRACE(ss.str());
- Global("lhs", lhs_type, ast::StorageClass::kPrivate);
- Global("rhs", rhs_type, ast::StorageClass::kPrivate);
+ GlobalVar("lhs", lhs_type, ast::StorageClass::kPrivate);
+ GlobalVar("rhs", rhs_type, ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(params.op, Expr("lhs"), Expr("rhs"));
WrapInFunction(expr);
@@ -1580,8 +1588,8 @@
ss << FriendlyName(lhs_type) << " " << op << " " << FriendlyName(rhs_type);
SCOPED_TRACE(ss.str());
- Global("lhs", lhs_type, ast::StorageClass::kPrivate);
- Global("rhs", rhs_type, ast::StorageClass::kPrivate);
+ GlobalVar("lhs", lhs_type, ast::StorageClass::kPrivate);
+ GlobalVar("rhs", rhs_type, ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(Source{{12, 34}}, op, Expr("lhs"), Expr("rhs"));
WrapInFunction(expr);
@@ -1620,8 +1628,8 @@
is_valid_expr = vec_size == mat_cols;
}
- Global("lhs", lhs_type, ast::StorageClass::kPrivate);
- Global("rhs", rhs_type, ast::StorageClass::kPrivate);
+ GlobalVar("lhs", lhs_type, ast::StorageClass::kPrivate);
+ GlobalVar("rhs", rhs_type, ast::StorageClass::kPrivate);
auto* expr = Mul(Source{{12, 34}}, Expr("lhs"), Expr("rhs"));
WrapInFunction(expr);
@@ -1657,8 +1665,8 @@
auto* col = create<sem::Vector>(f32, lhs_mat_rows);
auto* result_type = create<sem::Matrix>(col, rhs_mat_cols);
- Global("lhs", lhs_type, ast::StorageClass::kPrivate);
- Global("rhs", rhs_type, ast::StorageClass::kPrivate);
+ GlobalVar("lhs", lhs_type, ast::StorageClass::kPrivate);
+ GlobalVar("rhs", rhs_type, ast::StorageClass::kPrivate);
auto* expr = Mul(Source{{12, 34}}, Expr("lhs"), Expr("rhs"));
WrapInFunction(expr);
@@ -1686,11 +1694,11 @@
auto op = GetParam();
if (op == ast::UnaryOp::kNot) {
- Global("ident", ty.vec4<bool>(), ast::StorageClass::kPrivate);
+ GlobalVar("ident", ty.vec4<bool>(), ast::StorageClass::kPrivate);
} else if (op == ast::UnaryOp::kNegation || op == ast::UnaryOp::kComplement) {
- Global("ident", ty.vec4<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("ident", ty.vec4<i32>(), ast::StorageClass::kPrivate);
} else {
- Global("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
}
auto* der = create<ast::UnaryOpExpression>(op, Expr("ident"));
WrapInFunction(der);
@@ -1727,11 +1735,11 @@
TEST_F(ResolverTest, StorageClass_SetForSampler) {
auto* t = ty.sampler(ast::SamplerKind::kSampler);
- auto* var = Global("var", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* var = GlobalVar("var", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1740,11 +1748,11 @@
TEST_F(ResolverTest, StorageClass_SetForTexture) {
auto* t = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
- auto* var = Global("var", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* var = GlobalVar("var", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1765,11 +1773,11 @@
// struct S { x : i32 };
// var<storage> g : S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
- auto* var = Global(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* var = GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1779,12 +1787,12 @@
TEST_F(ResolverTest, BindingPoint_SetForResources) {
// @group(1) @binding(2) var s1 : sampler;
// @group(3) @binding(4) var s2 : sampler;
- auto* s1 = Global(
+ auto* s1 = GlobalVar(
Sym(), ty.sampler(ast::SamplerKind::kSampler),
- ast::AttributeList{create<ast::GroupAttribute>(1), create<ast::BindingAttribute>(2)});
- auto* s2 = Global(
+ ast::AttributeList{create<ast::GroupAttribute>(1u), create<ast::BindingAttribute>(2u)});
+ auto* s2 = GlobalVar(
Sym(), ty.sampler(ast::SamplerKind::kSampler),
- ast::AttributeList{create<ast::GroupAttribute>(3), create<ast::BindingAttribute>(4)});
+ ast::AttributeList{create<ast::GroupAttribute>(3u), create<ast::BindingAttribute>(4u)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1805,11 +1813,11 @@
// ep_1 -> {}
// ep_2 -> {}
- Global("first", ty.f32(), ast::StorageClass::kPrivate);
- Global("second", ty.f32(), ast::StorageClass::kPrivate);
- Global("call_a", ty.f32(), ast::StorageClass::kPrivate);
- Global("call_b", ty.f32(), ast::StorageClass::kPrivate);
- Global("call_c", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("first", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("second", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("call_a", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("call_b", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("call_c", ty.f32(), ast::StorageClass::kPrivate);
auto* func_b = Func("b", {}, ty.f32(),
{
@@ -1949,8 +1957,8 @@
{
ProgramBuilder b;
auto* expr = b.Expr(1_i);
- b.Global("a", b.ty.i32(), ast::StorageClass::kPrivate, expr);
- b.Global("b", b.ty.i32(), ast::StorageClass::kPrivate, expr);
+ b.GlobalVar("a", b.ty.i32(), ast::StorageClass::kPrivate, expr);
+ b.GlobalVar("b", b.ty.i32(), ast::StorageClass::kPrivate, expr);
Resolver(&b).Resolve();
},
"internal compiler error: AST node 'tint::ast::IntLiteralExpression' was encountered twice "
@@ -1958,7 +1966,7 @@
}
TEST_F(ResolverTest, UnaryOp_Not) {
- Global("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* der = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr(Source{{12, 34}}, "ident"));
WrapInFunction(der);
@@ -1967,7 +1975,7 @@
}
TEST_F(ResolverTest, UnaryOp_Complement) {
- Global("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* der =
create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr(Source{{12, 34}}, "ident"));
WrapInFunction(der);
@@ -1977,7 +1985,7 @@
}
TEST_F(ResolverTest, UnaryOp_Negation) {
- Global("ident", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("ident", ty.u32(), ast::StorageClass::kPrivate);
auto* der =
create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr(Source{{12, 34}}, "ident"));
WrapInFunction(der);
@@ -1987,8 +1995,8 @@
}
TEST_F(ResolverTest, TextureSampler_TextureSample) {
- Global("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(1, 1));
- Global("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 2));
+ GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(1, 1));
+ GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 2));
auto* call = CallStmt(Call("textureSample", "t", "s", vec2<f32>(1_f, 2_f)));
const ast::Function* f =
@@ -2004,8 +2012,8 @@
}
TEST_F(ResolverTest, TextureSampler_TextureSampleInFunction) {
- Global("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(1, 1));
- Global("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 2));
+ GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(1, 1));
+ GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 2));
auto* inner_call = CallStmt(Call("textureSample", "t", "s", vec2<f32>(1_f, 2_f)));
const ast::Function* inner_func = Func("inner_func", {}, ty.void_(), {inner_call});
@@ -2027,8 +2035,8 @@
}
TEST_F(ResolverTest, TextureSampler_TextureSampleFunctionDiamondSameVariables) {
- Global("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(1, 1));
- Global("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 2));
+ GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(1, 1));
+ GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 2));
auto* inner_call_1 = CallStmt(Call("textureSample", "t", "s", vec2<f32>(1_f, 2_f)));
const ast::Function* inner_func_1 = Func("inner_func_1", {}, ty.void_(), {inner_call_1});
@@ -2059,9 +2067,11 @@
}
TEST_F(ResolverTest, TextureSampler_TextureSampleFunctionDiamondDifferentVariables) {
- Global("t1", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(1, 1));
- Global("t2", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(1, 2));
- Global("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 3));
+ GlobalVar("t1", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ GroupAndBinding(1, 1));
+ GlobalVar("t2", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ GroupAndBinding(1, 2));
+ GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(1, 3));
auto* inner_call_1 = CallStmt(Call("textureSample", "t1", "s", vec2<f32>(1_f, 2_f)));
const ast::Function* inner_func_1 = Func("inner_func_1", {}, ty.void_(), {inner_call_1});
@@ -2094,7 +2104,7 @@
}
TEST_F(ResolverTest, TextureSampler_TextureDimensions) {
- Global("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(1, 2));
+ GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), GroupAndBinding(1, 2));
auto* call = Call("textureDimensions", "t");
const ast::Function* f = WrapInFunction(call);
@@ -2110,15 +2120,15 @@
TEST_F(ResolverTest, ModuleDependencyOrderedDeclarations) {
auto* f0 = Func("f0", {}, ty.void_(), {});
- auto* v0 = Global("v0", ty.i32(), ast::StorageClass::kPrivate);
+ auto* v0 = GlobalVar("v0", ty.i32(), ast::StorageClass::kPrivate);
auto* a0 = Alias("a0", ty.i32());
auto* s0 = Structure("s0", {Member("m", ty.i32())});
auto* f1 = Func("f1", {}, ty.void_(), {});
- auto* v1 = Global("v1", ty.i32(), ast::StorageClass::kPrivate);
+ auto* v1 = GlobalVar("v1", ty.i32(), ast::StorageClass::kPrivate);
auto* a1 = Alias("a1", ty.i32());
auto* s1 = Structure("s1", {Member("m", ty.i32())});
auto* f2 = Func("f2", {}, ty.void_(), {});
- auto* v2 = Global("v2", ty.i32(), ast::StorageClass::kPrivate);
+ auto* v2 = GlobalVar("v2", ty.i32(), ast::StorageClass::kPrivate);
auto* a2 = Alias("a2", ty.i32());
auto* s2 = Structure("s2", {Member("m", ty.i32())});
diff --git a/src/tint/resolver/resolver_test_helper.h b/src/tint/resolver/resolver_test_helper.h
index a0d71e5..f56d822 100644
--- a/src/tint/resolver/resolver_test_helper.h
+++ b/src/tint/resolver/resolver_test_helper.h
@@ -519,7 +519,7 @@
/// @return a new AST expression of the alias type
static inline const ast::Expression* Expr(ProgramBuilder& b, double /*unused*/) {
auto sym = b.Symbols().New("global_for_ptr");
- b.Global(sym, DataType<T>::AST(b), ast::StorageClass::kPrivate);
+ b.GlobalVar(sym, DataType<T>::AST(b), ast::StorageClass::kPrivate);
return b.AddressOf(sym);
}
/// @returns the WGSL name for the type
diff --git a/src/tint/resolver/side_effects_test.cc b/src/tint/resolver/side_effects_test.cc
index a50d904..689c7b8 100644
--- a/src/tint/resolver/side_effects_test.cc
+++ b/src/tint/resolver/side_effects_test.cc
@@ -17,6 +17,7 @@
#include "gtest/gtest.h"
#include "src/tint/resolver/resolver_test_helper.h"
#include "src/tint/sem/expression.h"
+#include "src/tint/sem/index_accessor_expression.h"
#include "src/tint/sem/member_accessor_expression.h"
using namespace tint::number_suffixes; // NOLINT
@@ -28,7 +29,7 @@
template <typename T>
void MakeSideEffectFunc(const char* name) {
auto global = Sym();
- Global(global, ty.Of<T>(), ast::StorageClass::kPrivate);
+ GlobalVar(global, ty.Of<T>(), ast::StorageClass::kPrivate);
auto local = Sym();
Func(name, {}, ty.Of<T>(),
{
@@ -41,7 +42,7 @@
template <typename MAKE_TYPE_FUNC>
void MakeSideEffectFunc(const char* name, MAKE_TYPE_FUNC make_type) {
auto global = Sym();
- Global(global, make_type(), ast::StorageClass::kPrivate);
+ GlobalVar(global, make_type(), ast::StorageClass::kPrivate);
auto local = Sym();
Func(name, {}, make_type(),
{
@@ -86,7 +87,7 @@
}
TEST_F(SideEffectsTest, Call_Builtin_NoSE) {
- Global("a", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call("dpdx", "a");
Func("f", {}, ty.void_(), {Ignore(expr)},
{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
@@ -112,7 +113,7 @@
}
TEST_F(SideEffectsTest, Call_Builtin_SE) {
- Global("a", ty.atomic(ty.i32()), ast::StorageClass::kWorkgroup);
+ GlobalVar("a", ty.atomic(ty.i32()), ast::StorageClass::kWorkgroup);
auto* expr = Call("atomicAdd", AddressOf("a"), 1_i);
WrapInFunction(expr);
diff --git a/src/tint/resolver/source_variable_test.cc b/src/tint/resolver/source_variable_test.cc
index cd943f3..2648e93 100644
--- a/src/tint/resolver/source_variable_test.cc
+++ b/src/tint/resolver/source_variable_test.cc
@@ -15,6 +15,7 @@
#include "src/tint/resolver/resolver.h"
#include "src/tint/resolver/resolver_test_helper.h"
+#include "src/tint/sem/index_accessor_expression.h"
#include "src/tint/sem/member_accessor_expression.h"
using namespace tint::number_suffixes; // NOLINT
@@ -25,7 +26,7 @@
class ResolverSourceVariableTest : public ResolverTest {};
TEST_F(ResolverSourceVariableTest, GlobalPrivateVar) {
- auto* a = Global("a", ty.f32(), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Expr(a);
WrapInFunction(expr);
@@ -36,7 +37,7 @@
}
TEST_F(ResolverSourceVariableTest, GlobalWorkgroupVar) {
- auto* a = Global("a", ty.f32(), ast::StorageClass::kWorkgroup);
+ auto* a = GlobalVar("a", ty.f32(), ast::StorageClass::kWorkgroup);
auto* expr = Expr(a);
WrapInFunction(expr);
@@ -47,7 +48,7 @@
}
TEST_F(ResolverSourceVariableTest, GlobalStorageVar) {
- auto* a = Global("a", ty.f32(), ast::StorageClass::kStorage, GroupAndBinding(0, 0));
+ auto* a = GlobalVar("a", ty.f32(), ast::StorageClass::kStorage, GroupAndBinding(0, 0));
auto* expr = Expr(a);
WrapInFunction(expr);
@@ -58,7 +59,7 @@
}
TEST_F(ResolverSourceVariableTest, GlobalUniformVar) {
- auto* a = Global("a", ty.f32(), ast::StorageClass::kUniform, GroupAndBinding(0, 0));
+ auto* a = GlobalVar("a", ty.f32(), ast::StorageClass::kUniform, GroupAndBinding(0, 0));
auto* expr = Expr(a);
WrapInFunction(expr);
@@ -69,8 +70,8 @@
}
TEST_F(ResolverSourceVariableTest, GlobalTextureVar) {
- auto* a = Global("a", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
- ast::StorageClass::kNone, GroupAndBinding(0, 0));
+ auto* a = GlobalVar("a", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ ast::StorageClass::kNone, GroupAndBinding(0, 0));
auto* expr = Expr(a);
WrapInFunction(Call("textureDimensions", expr));
@@ -196,7 +197,7 @@
// {
// a[2i]
// }
- auto* a = Global("a", ty.array(ty.f32(), 4_u), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.array(ty.f32(), 4_u), ast::StorageClass::kPrivate);
auto* expr = IndexAccessor(a, 2_i);
WrapInFunction(expr);
@@ -213,7 +214,7 @@
// a.f
// }
auto* S = Structure("S", {Member("f", ty.f32())});
- auto* a = Global("a", ty.Of(S), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.Of(S), ast::StorageClass::kPrivate);
auto* expr = MemberAccessor(a, "f");
WrapInFunction(expr);
@@ -229,7 +230,7 @@
// let a_ptr1 = &*&a;
// let a_ptr2 = &*a_ptr1;
// }
- auto* a = Global("a", ty.f32(), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
auto* address_of_1 = AddressOf(a);
auto* deref_1 = Deref(address_of_1);
auto* address_of_2 = AddressOf(deref_1);
diff --git a/src/tint/resolver/storage_class_layout_validation_test.cc b/src/tint/resolver/storage_class_layout_validation_test.cc
index db379a0..770361a 100644
--- a/src/tint/resolver/storage_class_layout_validation_test.cc
+++ b/src/tint/resolver/storage_class_layout_validation_test.cc
@@ -37,8 +37,8 @@
{Member("a", ty.f32(), {MemberSize(5)}),
Member(Source{{34, 56}}, "b", ty.f32(), {MemberAlign(1)})});
- Global(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kStorage,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kStorage,
+ GroupAndBinding(0, 0));
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -65,8 +65,8 @@
{Member("a", ty.f32(), {MemberSize(5)}),
Member(Source{{34, 56}}, "b", ty.f32(), {MemberAlign(4)})});
- Global(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kStorage,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kStorage,
+ GroupAndBinding(0, 0));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -93,8 +93,8 @@
Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
});
- Global(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -134,8 +134,8 @@
Member(Source{{56, 78}}, "inner", ty.type_name("Inner"), {MemberAlign(16)}),
});
- Global(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -159,8 +159,8 @@
Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
});
- Global(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -192,8 +192,8 @@
Member(Source{{34, 56}}, "inner", ty.type_name("Inner"), {MemberAlign(16)}),
});
- Global(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -222,8 +222,8 @@
Member(Source{{78, 90}}, "scalar", ty.i32()),
});
- Global(Source{{22, 24}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{22, 24}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -274,8 +274,8 @@
Member(Source{{78, 90}}, "scalar", ty.i32()),
});
- Global(Source{{22, 24}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{22, 24}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -320,8 +320,8 @@
Member(Source{{78, 90}}, "scalar", ty.i32(), {MemberAlign(16)}),
});
- Global(Source{{22, 34}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{22, 34}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -341,8 +341,8 @@
Member("s", ty.f32()),
});
- Global(Source{{78, 90}}, "a", ty.type_name("ScalarPackedAtEndOfVec3"),
- ast::StorageClass::kUniform, GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("ScalarPackedAtEndOfVec3"),
+ ast::StorageClass::kUniform, GroupAndBinding(0, 0));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -367,8 +367,8 @@
Member("scalar", ty.i32()),
});
- Global(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -401,8 +401,8 @@
Member("scalar", ty.i32()),
});
- Global(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -444,8 +444,8 @@
Member("scalar", ty.i32()),
});
- Global(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -462,8 +462,8 @@
TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_TopLevelArray) {
// @group(0) @binding(0)
// var<uniform> a : array<f32, 4u>;
- Global(Source{{78, 90}}, "a", ty.array(Source{{34, 56}}, ty.f32(), 4_u),
- ast::StorageClass::kUniform, GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.array(Source{{34, 56}}, ty.f32(), 4_u),
+ ast::StorageClass::kUniform, GroupAndBinding(0, 0));
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -484,8 +484,8 @@
Member("inner", ty.array(Source{{34, 56}}, ty.array(ty.f32(), 4_u), 4_u)),
});
- Global(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -517,8 +517,8 @@
Member("scalar", ty.i32()),
});
- Global(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
- GroupAndBinding(0, 0));
+ GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
+ GroupAndBinding(0, 0));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
diff --git a/src/tint/resolver/storage_class_validation_test.cc b/src/tint/resolver/storage_class_validation_test.cc
index a5e7d12..0e2be29 100644
--- a/src/tint/resolver/storage_class_validation_test.cc
+++ b/src/tint/resolver/storage_class_validation_test.cc
@@ -27,7 +27,7 @@
TEST_F(ResolverStorageClassValidationTest, GlobalVariableNoStorageClass_Fail) {
// var g : f32;
- Global(Source{{12, 34}}, "g", ty.f32(), ast::StorageClass::kNone);
+ GlobalVar(Source{{12, 34}}, "g", ty.f32(), ast::StorageClass::kNone);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -36,7 +36,7 @@
TEST_F(ResolverStorageClassValidationTest, GlobalVariableFunctionStorageClass_Fail) {
// var<function> g : f32;
- Global(Source{{12, 34}}, "g", ty.f32(), ast::StorageClass::kFunction);
+ GlobalVar(Source{{12, 34}}, "g", ty.f32(), ast::StorageClass::kFunction);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -44,96 +44,96 @@
}
TEST_F(ResolverStorageClassValidationTest, Private_RuntimeArray) {
- Global(Source{{12, 34}}, "v", ty.array(ty.i32()), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{12, 34}}, "v", ty.array(ty.i32()), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
-12:34 note: while instantiating variable v)");
+12:34 note: while instantiating 'var' v)");
}
TEST_F(ResolverStorageClassValidationTest, Private_RuntimeArrayInStruct) {
auto* s = Structure("S", {Member("m", ty.array(ty.i32()))});
- Global(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
note: while analysing structure member S.m
-12:34 note: while instantiating variable v)");
+12:34 note: while instantiating 'var' v)");
}
TEST_F(ResolverStorageClassValidationTest, Workgroup_RuntimeArray) {
- Global(Source{{12, 34}}, "v", ty.array(ty.i32()), ast::StorageClass::kWorkgroup);
+ GlobalVar(Source{{12, 34}}, "v", ty.array(ty.i32()), ast::StorageClass::kWorkgroup);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
-12:34 note: while instantiating variable v)");
+12:34 note: while instantiating 'var' v)");
}
TEST_F(ResolverStorageClassValidationTest, Workgroup_RuntimeArrayInStruct) {
auto* s = Structure("S", {Member("m", ty.array(ty.i32()))});
- Global(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kWorkgroup);
+ GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kWorkgroup);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
note: while analysing structure member S.m
-12:34 note: while instantiating variable v)");
+12:34 note: while instantiating 'var' v)");
}
TEST_F(ResolverStorageClassValidationTest, StorageBufferBool) {
// var<storage> g : bool;
- Global(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kStorage,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kStorage,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) {
// var<storage> g : ptr<private, f32>;
- Global(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
- ast::StorageClass::kStorage,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
+ ast::StorageClass::kStorage,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in storage class 'storage' as it is non-host-shareable
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverStorageClassValidationTest, StorageBufferIntScalar) {
// var<storage> g : i32;
- Global(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kStorage,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kStorage,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverStorageClassValidationTest, StorageBufferVector) {
// var<storage> g : vec4<f32>;
- Global(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kStorage,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kStorage,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -142,11 +142,11 @@
// var<storage, read> g : array<S, 3u>;
auto* s = Structure("S", {Member("a", ty.f32())});
auto* a = ty.array(ty.Of(s), 3_u);
- Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -155,23 +155,23 @@
// type a = bool;
// var<storage, read> g : a;
auto* a = Alias("a", ty.bool_());
- Global(Source{{56, 78}}, "g", ty.Of(a), ast::StorageClass::kStorage,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(a), ast::StorageClass::kStorage,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverStorageClassValidationTest, NotStorage_AccessMode) {
// var<private, read> g : a;
- Global(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kPrivate, ast::Access::kRead);
+ GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kPrivate, ast::Access::kRead);
ASSERT_FALSE(r()->Resolve());
@@ -184,11 +184,11 @@
// struct S { x : i32 };
// var<storage, read> g : S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
- Global(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_TRUE(r()->Resolve());
}
@@ -200,11 +200,11 @@
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
auto* a1 = Alias("a1", ty.Of(s));
auto* a2 = Alias("a2", ty.Of(a1));
- Global(Source{{56, 78}}, "g", ty.Of(a2), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_TRUE(r()->Resolve());
}
@@ -215,70 +215,70 @@
auto* s = Structure(Source{{12, 34}}, "S", {Member("m", ty.array<i32>())});
- Global(Source{{56, 78}}, "svar", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "svar", ty.Of(s), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(56:78 error: runtime-sized arrays can only be used in the <storage> storage class
note: while analysing structure member S.m
-56:78 note: while instantiating variable svar)");
+56:78 note: while instantiating 'var' svar)");
}
TEST_F(ResolverStorageClassValidationTest, UniformBufferBool) {
// var<uniform> g : bool;
- Global(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(56:78 error: Type 'bool' cannot be used in storage class 'uniform' as it is non-host-shareable
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverStorageClassValidationTest, UniformBufferPointer) {
// var<uniform> g : ptr<private, f32>;
- Global(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
- ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
+ ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in storage class 'uniform' as it is non-host-shareable
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverStorageClassValidationTest, UniformBufferIntScalar) {
// var<uniform> g : i32;
- Global(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverStorageClassValidationTest, UniformBufferVector) {
// var<uniform> g : vec4<f32>;
- Global(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -290,11 +290,11 @@
// var<uniform> g : array<S, 3u>;
auto* s = Structure("S", {Member("a", ty.f32(), {MemberSize(16)})});
auto* a = ty.array(ty.Of(s), 3_u);
- Global(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -303,29 +303,29 @@
// type a = bool;
// var<uniform> g : a;
auto* a = Alias("a", ty.bool_());
- Global(Source{{56, 78}}, "g", ty.Of(a), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(a), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(56:78 error: Type 'bool' cannot be used in storage class 'uniform' as it is non-host-shareable
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverStorageClassValidationTest, UniformBufferNoError_Basic) {
// struct S { x : i32 };
// var<uniform> g : S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
- Global(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
@@ -336,11 +336,11 @@
// var<uniform> g : a1;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
auto* a1 = Alias("a1", ty.Of(s));
- Global(Source{{56, 78}}, "g", ty.Of(a1), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{56, 78}}, "g", ty.Of(a1), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
diff --git a/src/tint/resolver/struct_layout_test.cc b/src/tint/resolver/struct_layout_test.cc
index 854e87a..73ecd4e 100644
--- a/src/tint/resolver/struct_layout_test.cc
+++ b/src/tint/resolver/struct_layout_test.cc
@@ -49,6 +49,60 @@
EXPECT_EQ(sem->Members()[2]->Offset(), 8u);
EXPECT_EQ(sem->Members()[2]->Align(), 4u);
EXPECT_EQ(sem->Members()[2]->Size(), 4u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
+}
+
+TEST_F(ResolverStructLayoutTest, ScalarsWithF16) {
+ Enable(ast::Extension::kF16);
+
+ auto* s = Structure("S", {
+ Member("a", ty.f32()),
+ Member("b", ty.f16()),
+ Member("c", ty.u32()),
+ Member("d", ty.f16()),
+ Member("e", ty.f16()),
+ Member("f", ty.i32()),
+ Member("g", ty.f16()),
+ });
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = TypeOf(s)->As<sem::Struct>();
+ ASSERT_NE(sem, nullptr);
+ EXPECT_EQ(sem->Size(), 24u);
+ EXPECT_EQ(sem->SizeNoPadding(), 22u);
+ EXPECT_EQ(sem->Align(), 4u);
+ ASSERT_EQ(sem->Members().size(), 7u);
+ // f32
+ EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
+ EXPECT_EQ(sem->Members()[0]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[0]->Size(), 4u);
+ // f16
+ EXPECT_EQ(sem->Members()[1]->Offset(), 4u);
+ EXPECT_EQ(sem->Members()[1]->Align(), 2u);
+ EXPECT_EQ(sem->Members()[1]->Size(), 2u);
+ // u32
+ EXPECT_EQ(sem->Members()[2]->Offset(), 8u);
+ EXPECT_EQ(sem->Members()[2]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[2]->Size(), 4u);
+ // f16
+ EXPECT_EQ(sem->Members()[3]->Offset(), 12u);
+ EXPECT_EQ(sem->Members()[3]->Align(), 2u);
+ EXPECT_EQ(sem->Members()[3]->Size(), 2u);
+ // f16
+ EXPECT_EQ(sem->Members()[4]->Offset(), 14u);
+ EXPECT_EQ(sem->Members()[4]->Align(), 2u);
+ EXPECT_EQ(sem->Members()[4]->Size(), 2u);
+ // i32
+ EXPECT_EQ(sem->Members()[5]->Offset(), 16u);
+ EXPECT_EQ(sem->Members()[5]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[5]->Size(), 4u);
+ // f16
+ EXPECT_EQ(sem->Members()[6]->Offset(), 20u);
+ EXPECT_EQ(sem->Members()[6]->Align(), 2u);
+ EXPECT_EQ(sem->Members()[6]->Size(), 2u);
}
TEST_F(ResolverStructLayoutTest, Alias) {
@@ -74,58 +128,89 @@
EXPECT_EQ(sem->Members()[1]->Offset(), 4u);
EXPECT_EQ(sem->Members()[1]->Align(), 4u);
EXPECT_EQ(sem->Members()[1]->Size(), 4u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayStaticSize) {
+ Enable(ast::Extension::kF16);
+
auto* s = Structure("S", {
Member("a", ty.array<i32, 3>()),
Member("b", ty.array<f32, 5>()),
- Member("c", ty.array<f32, 1>()),
+ Member("c", ty.array<f16, 7>()),
+ Member("d", ty.array<f32, 1>()),
});
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
ASSERT_NE(sem, nullptr);
- EXPECT_EQ(sem->Size(), 36u);
- EXPECT_EQ(sem->SizeNoPadding(), 36u);
+ EXPECT_EQ(sem->Size(), 52u);
+ EXPECT_EQ(sem->SizeNoPadding(), 52u);
EXPECT_EQ(sem->Align(), 4u);
- ASSERT_EQ(sem->Members().size(), 3u);
+ ASSERT_EQ(sem->Members().size(), 4u);
+ // array<i32, 3>
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 12u);
+ // array<f32, 5>
EXPECT_EQ(sem->Members()[1]->Offset(), 12u);
EXPECT_EQ(sem->Members()[1]->Align(), 4u);
EXPECT_EQ(sem->Members()[1]->Size(), 20u);
+ // array<f16, 7>
EXPECT_EQ(sem->Members()[2]->Offset(), 32u);
- EXPECT_EQ(sem->Members()[2]->Align(), 4u);
- EXPECT_EQ(sem->Members()[2]->Size(), 4u);
+ EXPECT_EQ(sem->Members()[2]->Align(), 2u);
+ EXPECT_EQ(sem->Members()[2]->Size(), 14u);
+ // array<f32, 1>
+ EXPECT_EQ(sem->Members()[3]->Offset(), 48u);
+ EXPECT_EQ(sem->Members()[3]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[3]->Size(), 4u);
+
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayStaticSize) {
+ Enable(ast::Extension::kF16);
+
auto* s = Structure("S", {
Member("a", ty.array<i32, 3>(/*stride*/ 8)),
Member("b", ty.array<f32, 5>(/*stride*/ 16)),
- Member("c", ty.array<f32, 1>(/*stride*/ 32)),
+ Member("c", ty.array<f16, 7>(/*stride*/ 4)),
+ Member("d", ty.array<f32, 1>(/*stride*/ 32)),
});
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
ASSERT_NE(sem, nullptr);
- EXPECT_EQ(sem->Size(), 136u);
- EXPECT_EQ(sem->SizeNoPadding(), 136u);
+ EXPECT_EQ(sem->Size(), 164u);
+ EXPECT_EQ(sem->SizeNoPadding(), 164u);
EXPECT_EQ(sem->Align(), 4u);
- ASSERT_EQ(sem->Members().size(), 3u);
+ ASSERT_EQ(sem->Members().size(), 4u);
+ // array<i32, 3>, stride = 8
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 24u);
+ // array<f32, 5>, stride = 16
EXPECT_EQ(sem->Members()[1]->Offset(), 24u);
EXPECT_EQ(sem->Members()[1]->Align(), 4u);
EXPECT_EQ(sem->Members()[1]->Size(), 80u);
+ // array<f16, 7>, stride = 4
EXPECT_EQ(sem->Members()[2]->Offset(), 104u);
- EXPECT_EQ(sem->Members()[2]->Align(), 4u);
- EXPECT_EQ(sem->Members()[2]->Size(), 32u);
+ EXPECT_EQ(sem->Members()[2]->Align(), 2u);
+ EXPECT_EQ(sem->Members()[2]->Size(), 28u);
+ // array<f32, 1>, stride = 32
+ EXPECT_EQ(sem->Members()[3]->Offset(), 132u);
+ EXPECT_EQ(sem->Members()[3]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[3]->Size(), 32u);
+
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayRuntimeSized) {
@@ -144,6 +229,9 @@
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 4u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayRuntimeSized) {
@@ -162,6 +250,9 @@
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 32u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfExplicitStrideArray) {
@@ -182,6 +273,9 @@
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 384u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfStructure) {
@@ -206,6 +300,9 @@
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 16u);
EXPECT_EQ(sem->Members()[0]->Size(), 576u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, Vector) {
@@ -232,56 +329,101 @@
EXPECT_EQ(sem->Members()[2]->Offset(), 32u); // vec4
EXPECT_EQ(sem->Members()[2]->Align(), 16u);
EXPECT_EQ(sem->Members()[2]->Size(), 16u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, Matrix) {
+ Enable(ast::Extension::kF16);
+
auto* s = Structure("S", {
- Member("a", ty.mat2x2<f32>()),
- Member("b", ty.mat2x3<f32>()),
- Member("c", ty.mat2x4<f32>()),
- Member("d", ty.mat3x2<f32>()),
- Member("e", ty.mat3x3<f32>()),
- Member("f", ty.mat3x4<f32>()),
- Member("g", ty.mat4x2<f32>()),
- Member("h", ty.mat4x3<f32>()),
- Member("i", ty.mat4x4<f32>()),
+ Member("a_1", ty.mat2x2<f32>()),
+ Member("a_2", ty.mat2x2<f16>()),
+ Member("b_1", ty.mat2x3<f32>()),
+ Member("b_2", ty.mat2x3<f16>()),
+ Member("c_1", ty.mat2x4<f32>()),
+ Member("c_2", ty.mat2x4<f16>()),
+ Member("d_1", ty.mat3x2<f32>()),
+ Member("d_2", ty.mat3x2<f16>()),
+ Member("e_1", ty.mat3x3<f32>()),
+ Member("e_2", ty.mat3x3<f16>()),
+ Member("f_1", ty.mat3x4<f32>()),
+ Member("f_2", ty.mat3x4<f16>()),
+ Member("g_1", ty.mat4x2<f32>()),
+ Member("g_2", ty.mat4x2<f16>()),
+ Member("h_1", ty.mat4x3<f32>()),
+ Member("h_2", ty.mat4x3<f16>()),
+ Member("i_1", ty.mat4x4<f32>()),
+ Member("i_2", ty.mat4x4<f16>()),
});
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = TypeOf(s)->As<sem::Struct>();
ASSERT_NE(sem, nullptr);
- EXPECT_EQ(sem->Size(), 368u);
- EXPECT_EQ(sem->SizeNoPadding(), 368u);
+ EXPECT_EQ(sem->Size(), 576u);
+ EXPECT_EQ(sem->SizeNoPadding(), 576u);
EXPECT_EQ(sem->Align(), 16u);
- ASSERT_EQ(sem->Members().size(), 9u);
- EXPECT_EQ(sem->Members()[0]->Offset(), 0u); // mat2x2
+ ASSERT_EQ(sem->Members().size(), 18u);
+ EXPECT_EQ(sem->Members()[0]->Offset(), 0u); // mat2x2<f32>
EXPECT_EQ(sem->Members()[0]->Align(), 8u);
EXPECT_EQ(sem->Members()[0]->Size(), 16u);
- EXPECT_EQ(sem->Members()[1]->Offset(), 16u); // mat2x3
- EXPECT_EQ(sem->Members()[1]->Align(), 16u);
- EXPECT_EQ(sem->Members()[1]->Size(), 32u);
- EXPECT_EQ(sem->Members()[2]->Offset(), 48u); // mat2x4
+ EXPECT_EQ(sem->Members()[1]->Offset(), 16u); // mat2x2<f16>
+ EXPECT_EQ(sem->Members()[1]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[1]->Size(), 8u);
+ EXPECT_EQ(sem->Members()[2]->Offset(), 32u); // mat2x3<f32>
EXPECT_EQ(sem->Members()[2]->Align(), 16u);
EXPECT_EQ(sem->Members()[2]->Size(), 32u);
- EXPECT_EQ(sem->Members()[3]->Offset(), 80u); // mat3x2
+ EXPECT_EQ(sem->Members()[3]->Offset(), 64u); // mat2x3<f16>
EXPECT_EQ(sem->Members()[3]->Align(), 8u);
- EXPECT_EQ(sem->Members()[3]->Size(), 24u);
- EXPECT_EQ(sem->Members()[4]->Offset(), 112u); // mat3x3
+ EXPECT_EQ(sem->Members()[3]->Size(), 16u);
+ EXPECT_EQ(sem->Members()[4]->Offset(), 80u); // mat2x4<f32>
EXPECT_EQ(sem->Members()[4]->Align(), 16u);
- EXPECT_EQ(sem->Members()[4]->Size(), 48u);
- EXPECT_EQ(sem->Members()[5]->Offset(), 160u); // mat3x4
- EXPECT_EQ(sem->Members()[5]->Align(), 16u);
- EXPECT_EQ(sem->Members()[5]->Size(), 48u);
- EXPECT_EQ(sem->Members()[6]->Offset(), 208u); // mat4x2
+ EXPECT_EQ(sem->Members()[4]->Size(), 32u);
+ EXPECT_EQ(sem->Members()[5]->Offset(), 112u); // mat2x4<f16>
+ EXPECT_EQ(sem->Members()[5]->Align(), 8u);
+ EXPECT_EQ(sem->Members()[5]->Size(), 16u);
+ EXPECT_EQ(sem->Members()[6]->Offset(), 128u); // mat3x2<f32>
EXPECT_EQ(sem->Members()[6]->Align(), 8u);
- EXPECT_EQ(sem->Members()[6]->Size(), 32u);
- EXPECT_EQ(sem->Members()[7]->Offset(), 240u); // mat4x3
- EXPECT_EQ(sem->Members()[7]->Align(), 16u);
- EXPECT_EQ(sem->Members()[7]->Size(), 64u);
- EXPECT_EQ(sem->Members()[8]->Offset(), 304u); // mat4x4
+ EXPECT_EQ(sem->Members()[6]->Size(), 24u);
+ EXPECT_EQ(sem->Members()[7]->Offset(), 152u); // mat3x2<f16>
+ EXPECT_EQ(sem->Members()[7]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[7]->Size(), 12u);
+ EXPECT_EQ(sem->Members()[8]->Offset(), 176u); // mat3x3<f32>
EXPECT_EQ(sem->Members()[8]->Align(), 16u);
- EXPECT_EQ(sem->Members()[8]->Size(), 64u);
+ EXPECT_EQ(sem->Members()[8]->Size(), 48u);
+ EXPECT_EQ(sem->Members()[9]->Offset(), 224u); // mat3x3<f16>
+ EXPECT_EQ(sem->Members()[9]->Align(), 8u);
+ EXPECT_EQ(sem->Members()[9]->Size(), 24u);
+ EXPECT_EQ(sem->Members()[10]->Offset(), 256u); // mat3x4<f32>
+ EXPECT_EQ(sem->Members()[10]->Align(), 16u);
+ EXPECT_EQ(sem->Members()[10]->Size(), 48u);
+ EXPECT_EQ(sem->Members()[11]->Offset(), 304u); // mat3x4<f16>
+ EXPECT_EQ(sem->Members()[11]->Align(), 8u);
+ EXPECT_EQ(sem->Members()[11]->Size(), 24u);
+ EXPECT_EQ(sem->Members()[12]->Offset(), 328u); // mat4x2<f32>
+ EXPECT_EQ(sem->Members()[12]->Align(), 8u);
+ EXPECT_EQ(sem->Members()[12]->Size(), 32u);
+ EXPECT_EQ(sem->Members()[13]->Offset(), 360u); // mat4x2<f16>
+ EXPECT_EQ(sem->Members()[13]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[13]->Size(), 16u);
+ EXPECT_EQ(sem->Members()[14]->Offset(), 384u); // mat4x3<f32>
+ EXPECT_EQ(sem->Members()[14]->Align(), 16u);
+ EXPECT_EQ(sem->Members()[14]->Size(), 64u);
+ EXPECT_EQ(sem->Members()[15]->Offset(), 448u); // mat4x3<f16>
+ EXPECT_EQ(sem->Members()[15]->Align(), 8u);
+ EXPECT_EQ(sem->Members()[15]->Size(), 32u);
+ EXPECT_EQ(sem->Members()[16]->Offset(), 480u); // mat4x4<f32>
+ EXPECT_EQ(sem->Members()[16]->Align(), 16u);
+ EXPECT_EQ(sem->Members()[16]->Size(), 64u);
+ EXPECT_EQ(sem->Members()[17]->Offset(), 544u); // mat4x4<f16>
+ EXPECT_EQ(sem->Members()[17]->Align(), 8u);
+ EXPECT_EQ(sem->Members()[17]->Size(), 32u);
+
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, NestedStruct) {
@@ -311,6 +453,9 @@
EXPECT_EQ(sem->Members()[2]->Offset(), 64u);
EXPECT_EQ(sem->Members()[2]->Align(), 4u);
EXPECT_EQ(sem->Members()[2]->Size(), 4u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, SizeAttributes) {
@@ -346,6 +491,9 @@
EXPECT_EQ(sem->Members()[3]->Offset(), 44u);
EXPECT_EQ(sem->Members()[3]->Align(), 4u);
EXPECT_EQ(sem->Members()[3]->Size(), 32u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, AlignAttributes) {
@@ -381,6 +529,9 @@
EXPECT_EQ(sem->Members()[3]->Offset(), 64u);
EXPECT_EQ(sem->Members()[3]->Align(), 32u);
EXPECT_EQ(sem->Members()[3]->Size(), 4u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
TEST_F(ResolverStructLayoutTest, StructWithLotsOfPadding) {
@@ -399,6 +550,9 @@
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 1024u);
EXPECT_EQ(sem->Members()[0]->Size(), 4u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
}
} // namespace
diff --git a/src/tint/resolver/struct_storage_class_use_test.cc b/src/tint/resolver/struct_storage_class_use_test.cc
index 72ed546..5a929a5 100644
--- a/src/tint/resolver/struct_storage_class_use_test.cc
+++ b/src/tint/resolver/struct_storage_class_use_test.cc
@@ -64,7 +64,7 @@
TEST_F(ResolverStorageClassUseTest, StructReachableFromGlobal) {
auto* s = Structure("S", {Member("a", ty.f32())});
- Global("g", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -76,7 +76,7 @@
TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalAlias) {
auto* s = Structure("S", {Member("a", ty.f32())});
auto* a = Alias("A", ty.Of(s));
- Global("g", ty.Of(a), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(a), ast::StorageClass::kPrivate);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -88,7 +88,7 @@
TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalStruct) {
auto* s = Structure("S", {Member("a", ty.f32())});
auto* o = Structure("O", {Member("a", ty.Of(s))});
- Global("g", ty.Of(o), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(o), ast::StorageClass::kPrivate);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -100,7 +100,7 @@
TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalArray) {
auto* s = Structure("S", {Member("a", ty.f32())});
auto* a = ty.array(ty.Of(s), 3_u);
- Global("g", a, ast::StorageClass::kPrivate);
+ GlobalVar("g", a, ast::StorageClass::kPrivate);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -159,16 +159,16 @@
TEST_F(ResolverStorageClassUseTest, StructMultipleStorageClassUses) {
auto* s = Structure("S", {Member("a", ty.f32())});
- Global("x", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
- Global("y", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("x", ty.Of(s), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
+ GlobalVar("y", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(0u),
+ });
WrapInFunction(Var("g", ty.Of(s)));
ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/type_constructor_validation_test.cc b/src/tint/resolver/type_constructor_validation_test.cc
index 3277ee8..1c857cd 100644
--- a/src/tint/resolver/type_constructor_validation_test.cc
+++ b/src/tint/resolver/type_constructor_validation_test.cc
@@ -83,6 +83,8 @@
// }
auto& params = GetParam();
+ Enable(ast::Extension::kF16);
+
auto* constructor_expr = params.create_rhs_ast_value(*this, 0);
auto* a = Var("a", nullptr, ast::StorageClass::kNone, constructor_expr);
@@ -104,18 +106,24 @@
ParamsFor<i32>(),
ParamsFor<u32>(),
ParamsFor<f32>(),
+ ParamsFor<f16>(),
ParamsFor<vec3<i32>>(),
ParamsFor<vec3<u32>>(),
ParamsFor<vec3<f32>>(),
+ ParamsFor<vec3<f16>>(),
ParamsFor<mat3x3<f32>>(),
+ ParamsFor<mat3x3<f16>>(),
ParamsFor<alias<bool>>(),
ParamsFor<alias<i32>>(),
ParamsFor<alias<u32>>(),
ParamsFor<alias<f32>>(),
+ ParamsFor<alias<f16>>(),
ParamsFor<alias<vec3<i32>>>(),
ParamsFor<alias<vec3<u32>>>(),
ParamsFor<alias<vec3<f32>>>(),
+ ParamsFor<alias<vec3<f16>>>(),
ParamsFor<alias<mat3x3<f32>>>(),
+ ParamsFor<alias<mat3x3<f16>>>(),
};
INSTANTIATE_TEST_SUITE_P(ResolverTypeConstructorValidationTest,
InferTypeTest_FromConstructorExpression,
@@ -176,6 +184,8 @@
// }
auto& params = GetParam();
+ Enable(ast::Extension::kF16);
+
Func("foo", {}, params.create_rhs_ast_type(*this),
{Return(Construct(params.create_rhs_ast_type(*this)))}, {});
@@ -197,18 +207,24 @@
ParamsFor<i32>(),
ParamsFor<u32>(),
ParamsFor<f32>(),
+ ParamsFor<f16>(),
ParamsFor<vec3<i32>>(),
ParamsFor<vec3<u32>>(),
ParamsFor<vec3<f32>>(),
+ ParamsFor<vec3<f16>>(),
ParamsFor<mat3x3<f32>>(),
+ ParamsFor<mat3x3<f16>>(),
ParamsFor<alias<bool>>(),
ParamsFor<alias<i32>>(),
ParamsFor<alias<u32>>(),
ParamsFor<alias<f32>>(),
+ ParamsFor<alias<f16>>(),
ParamsFor<alias<vec3<i32>>>(),
ParamsFor<alias<vec3<u32>>>(),
ParamsFor<alias<vec3<f32>>>(),
+ ParamsFor<alias<vec3<f16>>>(),
ParamsFor<alias<mat3x3<f32>>>(),
+ ParamsFor<alias<mat3x3<f16>>>(),
};
INSTANTIATE_TEST_SUITE_P(ResolverTypeConstructorValidationTest,
InferTypeTest_FromCallExpression,
@@ -240,19 +256,25 @@
ParamsFor<i32, i32>(Kind::Construct), //
ParamsFor<u32, u32>(Kind::Construct), //
ParamsFor<f32, f32>(Kind::Construct), //
+ ParamsFor<f16, f16>(Kind::Construct), //
ParamsFor<vec3<bool>, vec3<bool>>(Kind::Construct), //
ParamsFor<vec3<i32>, vec3<i32>>(Kind::Construct), //
ParamsFor<vec3<u32>, vec3<u32>>(Kind::Construct), //
ParamsFor<vec3<f32>, vec3<f32>>(Kind::Construct), //
+ ParamsFor<vec3<f16>, vec3<f16>>(Kind::Construct), //
ParamsFor<mat3x3<f32>, mat3x3<f32>>(Kind::Construct), //
ParamsFor<mat2x3<f32>, mat2x3<f32>>(Kind::Construct), //
ParamsFor<mat3x2<f32>, mat3x2<f32>>(Kind::Construct), //
+ ParamsFor<mat3x3<f16>, mat3x3<f16>>(Kind::Construct), //
+ ParamsFor<mat2x3<f16>, mat2x3<f16>>(Kind::Construct), //
+ ParamsFor<mat3x2<f16>, mat3x2<f16>>(Kind::Construct), //
// Splat
ParamsFor<vec3<bool>, bool>(Kind::Construct), //
ParamsFor<vec3<i32>, i32>(Kind::Construct), //
ParamsFor<vec3<u32>, u32>(Kind::Construct), //
ParamsFor<vec3<f32>, f32>(Kind::Construct), //
+ ParamsFor<vec3<f16>, f16>(Kind::Construct), //
ParamsFor<mat3x3<f32>, f32>(Kind::Construct), //
ParamsFor<mat2x3<f32>, f32>(Kind::Construct), //
@@ -262,40 +284,68 @@
ParamsFor<bool, u32>(Kind::Conversion), //
ParamsFor<bool, i32>(Kind::Conversion), //
ParamsFor<bool, f32>(Kind::Conversion), //
+ ParamsFor<bool, f16>(Kind::Conversion), //
ParamsFor<i32, bool>(Kind::Conversion), //
ParamsFor<i32, u32>(Kind::Conversion), //
ParamsFor<i32, f32>(Kind::Conversion), //
+ ParamsFor<i32, f16>(Kind::Conversion), //
ParamsFor<u32, bool>(Kind::Conversion), //
ParamsFor<u32, i32>(Kind::Conversion), //
ParamsFor<u32, f32>(Kind::Conversion), //
+ ParamsFor<u32, f16>(Kind::Conversion), //
ParamsFor<f32, bool>(Kind::Conversion), //
ParamsFor<f32, u32>(Kind::Conversion), //
ParamsFor<f32, i32>(Kind::Conversion), //
+ ParamsFor<f32, f16>(Kind::Conversion), //
+
+ ParamsFor<f16, bool>(Kind::Conversion), //
+ ParamsFor<f16, u32>(Kind::Conversion), //
+ ParamsFor<f16, i32>(Kind::Conversion), //
+ ParamsFor<f16, f32>(Kind::Conversion), //
ParamsFor<vec3<bool>, vec3<u32>>(Kind::Conversion), //
ParamsFor<vec3<bool>, vec3<i32>>(Kind::Conversion), //
ParamsFor<vec3<bool>, vec3<f32>>(Kind::Conversion), //
+ ParamsFor<vec3<bool>, vec3<f16>>(Kind::Conversion), //
ParamsFor<vec3<i32>, vec3<bool>>(Kind::Conversion), //
ParamsFor<vec3<i32>, vec3<u32>>(Kind::Conversion), //
ParamsFor<vec3<i32>, vec3<f32>>(Kind::Conversion), //
+ ParamsFor<vec3<i32>, vec3<f16>>(Kind::Conversion), //
ParamsFor<vec3<u32>, vec3<bool>>(Kind::Conversion), //
ParamsFor<vec3<u32>, vec3<i32>>(Kind::Conversion), //
ParamsFor<vec3<u32>, vec3<f32>>(Kind::Conversion), //
+ ParamsFor<vec3<u32>, vec3<f16>>(Kind::Conversion), //
ParamsFor<vec3<f32>, vec3<bool>>(Kind::Conversion), //
ParamsFor<vec3<f32>, vec3<u32>>(Kind::Conversion), //
ParamsFor<vec3<f32>, vec3<i32>>(Kind::Conversion), //
+ ParamsFor<vec3<f32>, vec3<f16>>(Kind::Conversion), //
+
+ ParamsFor<vec3<f16>, vec3<bool>>(Kind::Conversion), //
+ ParamsFor<vec3<f16>, vec3<u32>>(Kind::Conversion), //
+ ParamsFor<vec3<f16>, vec3<i32>>(Kind::Conversion), //
+ ParamsFor<vec3<f16>, vec3<f32>>(Kind::Conversion), //
+
+ ParamsFor<mat3x3<f16>, mat3x3<f32>>(Kind::Conversion), //
+ ParamsFor<mat2x3<f16>, mat2x3<f32>>(Kind::Conversion), //
+ ParamsFor<mat3x2<f16>, mat3x2<f32>>(Kind::Conversion), //
+
+ ParamsFor<mat3x3<f32>, mat3x3<f16>>(Kind::Conversion), //
+ ParamsFor<mat2x3<f32>, mat2x3<f16>>(Kind::Conversion), //
+ ParamsFor<mat3x2<f32>, mat3x2<f16>>(Kind::Conversion), //
};
using ConversionConstructorValidTest = ResolverTestWithParam<Params>;
TEST_P(ConversionConstructorValidTest, All) {
auto& params = GetParam();
+ Enable(ast::Extension::kF16);
+
// var a : <lhs_type1> = <lhs_type2>(<rhs_type>(<rhs_value_expr>));
auto* lhs_type1 = params.lhs_type(*this);
auto* lhs_type2 = params.lhs_type(*this);
@@ -348,19 +398,24 @@
CreatePtrsFor<u32>(), //
CreatePtrsFor<i32>(), //
CreatePtrsFor<f32>(), //
+ CreatePtrsFor<f16>(), //
CreatePtrsFor<vec3<bool>>(), //
CreatePtrsFor<vec3<i32>>(), //
CreatePtrsFor<vec3<u32>>(), //
CreatePtrsFor<vec3<f32>>(), //
+ CreatePtrsFor<vec3<f16>>(), //
CreatePtrsFor<mat3x3<i32>>(), //
CreatePtrsFor<mat3x3<u32>>(), //
CreatePtrsFor<mat3x3<f32>>(), //
+ CreatePtrsFor<mat3x3<f16>>(), //
CreatePtrsFor<mat2x3<i32>>(), //
CreatePtrsFor<mat2x3<u32>>(), //
CreatePtrsFor<mat2x3<f32>>(), //
+ CreatePtrsFor<mat2x3<f16>>(), //
CreatePtrsFor<mat3x2<i32>>(), //
CreatePtrsFor<mat3x2<u32>>(), //
- CreatePtrsFor<mat3x2<f32>>() //
+ CreatePtrsFor<mat3x2<f32>>(), //
+ CreatePtrsFor<mat3x2<f16>>(), //
};
using ConversionConstructorInvalidTest = ResolverTestWithParam<std::tuple<CreatePtrs, // lhs
@@ -395,6 +450,8 @@
<< FriendlyName(rhs_type) << "(<rhs value expr>))";
SCOPED_TRACE(ss.str());
+ Enable(ast::Extension::kF16);
+
auto* a = Var("a", lhs_type1, ast::StorageClass::kNone,
Construct(lhs_type2, Construct(rhs_type, rhs_value_expr)));
@@ -581,8 +638,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array constructor has too few elements: expected 4, "
- "found 3");
+ "12:34 error: array constructor has too few elements: expected 4, found 3");
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Array_TooManyElements) {
@@ -674,6 +730,26 @@
EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::F32>());
}
+TEST_F(ResolverTypeConstructorValidationTest, Expr_Construct_f16_Success) {
+ Enable(ast::Extension::kF16);
+
+ auto* expr = Construct<f16>(Expr(1.5_h));
+ WrapInFunction(expr);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(expr), nullptr);
+ ASSERT_TRUE(TypeOf(expr)->Is<sem::F16>());
+
+ auto* call = Sem().Get<sem::Call>(expr);
+ ASSERT_NE(call, nullptr);
+ auto* ctor = call->Target()->As<sem::TypeConstructor>();
+ ASSERT_NE(ctor, nullptr);
+ EXPECT_EQ(call->Type(), ctor->ReturnType());
+ ASSERT_EQ(ctor->Parameters().size(), 1u);
+ EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::F16>());
+}
+
TEST_F(ResolverTypeConstructorValidationTest, Expr_Convert_f32_to_i32_Success) {
auto* expr = Construct<i32>(1.23_f);
WrapInFunction(expr);
@@ -710,8 +786,30 @@
EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::I32>());
}
-TEST_F(ResolverTypeConstructorValidationTest, Expr_Convert_u32_to_f32_Success) {
- auto* expr = Construct<f32>(123_u);
+TEST_F(ResolverTypeConstructorValidationTest, Expr_Convert_u32_to_f16_Success) {
+ Enable(ast::Extension::kF16);
+
+ auto* expr = Construct<f16>(123_u);
+ WrapInFunction(expr);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(expr), nullptr);
+ ASSERT_TRUE(TypeOf(expr)->Is<sem::F16>());
+
+ auto* call = Sem().Get<sem::Call>(expr);
+ ASSERT_NE(call, nullptr);
+ auto* ctor = call->Target()->As<sem::TypeConversion>();
+ ASSERT_NE(ctor, nullptr);
+ EXPECT_EQ(call->Type(), ctor->ReturnType());
+ ASSERT_EQ(ctor->Parameters().size(), 1u);
+ EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::U32>());
+}
+
+TEST_F(ResolverTypeConstructorValidationTest, Expr_Convert_f16_to_f32_Success) {
+ Enable(ast::Extension::kF16);
+
+ auto* expr = Construct<f32>(123_h);
WrapInFunction(expr);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -725,7 +823,7 @@
ASSERT_NE(ctor, nullptr);
EXPECT_EQ(call->Type(), ctor->ReturnType());
ASSERT_EQ(ctor->Parameters().size(), 1u);
- EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::U32>());
+ EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::F16>());
}
} // namespace ScalarConstructor
@@ -742,6 +840,17 @@
}
TEST_F(ResolverTypeConstructorValidationTest,
+ Expr_Constructor_Vec2F16_Error_ScalarArgumentTypeMismatch) {
+ Enable(ast::Extension::kF16);
+
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<f16>(), 1_h, 2_f));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<f16>(f16, f32)"));
+}
+
+TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec2U32_Error_ScalarArgumentTypeMismatch) {
WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<u32>(), 1_u, 2_i));
@@ -860,6 +969,29 @@
EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::F32>());
}
+TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2F16_Success_Scalar) {
+ Enable(ast::Extension::kF16);
+
+ auto* tc = vec2<f16>(1_h, 1_h);
+ WrapInFunction(tc);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(tc), nullptr);
+ ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
+ EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F16>());
+ EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 2u);
+
+ auto* call = Sem().Get<sem::Call>(tc);
+ ASSERT_NE(call, nullptr);
+ auto* ctor = call->Target()->As<sem::TypeConstructor>();
+ ASSERT_NE(ctor, nullptr);
+ EXPECT_EQ(call->Type(), ctor->ReturnType());
+ ASSERT_EQ(ctor->Parameters().size(), 2u);
+ EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::F16>());
+ EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::F16>());
+}
+
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2U32_Success_Scalar) {
auto* tc = vec2<u32>(1_u, 1_u);
WrapInFunction(tc);
@@ -973,6 +1105,17 @@
}
TEST_F(ResolverTypeConstructorValidationTest,
+ Expr_Constructor_Vec3F16_Error_ScalarArgumentTypeMismatch) {
+ Enable(ast::Extension::kF16);
+
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<f16>(), 1_h, 2_h, 3_f));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f16>(f16, f16, f32)"));
+}
+
+TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec3U32_Error_ScalarArgumentTypeMismatch) {
WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<u32>(), 1_u, 2_i, 3_u));
@@ -1109,6 +1252,30 @@
EXPECT_TRUE(ctor->Parameters()[2]->Type()->Is<sem::F32>());
}
+TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3F16_Success_Scalar) {
+ Enable(ast::Extension::kF16);
+
+ auto* tc = vec3<f16>(1_h, 1_h, 1_h);
+ WrapInFunction(tc);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(tc), nullptr);
+ ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
+ EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F16>());
+ EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 3u);
+
+ auto* call = Sem().Get<sem::Call>(tc);
+ ASSERT_NE(call, nullptr);
+ auto* ctor = call->Target()->As<sem::TypeConstructor>();
+ ASSERT_NE(ctor, nullptr);
+ EXPECT_EQ(call->Type(), ctor->ReturnType());
+ ASSERT_EQ(ctor->Parameters().size(), 3u);
+ EXPECT_TRUE(ctor->Parameters()[0]->Type()->Is<sem::F16>());
+ EXPECT_TRUE(ctor->Parameters()[1]->Type()->Is<sem::F16>());
+ EXPECT_TRUE(ctor->Parameters()[2]->Type()->Is<sem::F16>());
+}
+
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3U32_Success_Scalar) {
auto* tc = vec3<u32>(1_u, 1_u, 1_u);
WrapInFunction(tc);
@@ -1268,6 +1435,18 @@
}
TEST_F(ResolverTypeConstructorValidationTest,
+ Expr_Constructor_Vec4F16_Error_ScalarArgumentTypeMismatch) {
+ Enable(ast::Extension::kF16);
+
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f16>(), 1_h, 1_h, 1_f, 1_h));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f16>(f16, f16, f32, f16)"));
+}
+
+TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4U32_Error_ScalarArgumentTypeMismatch) {
WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<u32>(), 1_u, 1_u, 1_i, 1_u));
@@ -1435,6 +1614,20 @@
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 4u);
}
+TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec4F16_Success_Scalar) {
+ Enable(ast::Extension::kF16);
+
+ auto* tc = vec4<f16>(1_h, 1_h, 1_h, 1_h);
+ WrapInFunction(tc);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(tc), nullptr);
+ ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
+ EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F16>());
+ EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 4u);
+}
+
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec4U32_Success_Scalar) {
auto* tc = vec4<u32>(1_u, 1_u, 1_u, 1_u);
WrapInFunction(tc);
@@ -1592,7 +1785,7 @@
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vector_Alias_Argument_Error) {
auto* alias = Alias("UnsignedInt", ty.u32());
- Global("uint_var", ty.Of(alias), ast::StorageClass::kPrivate);
+ GlobalVar("uint_var", ty.Of(alias), ast::StorageClass::kPrivate);
auto* tc = Construct(Source{{12, 34}}, ty.vec2<f32>(), "uint_var");
WrapInFunction(tc);
@@ -1604,8 +1797,8 @@
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vector_Alias_Argument_Success) {
auto* f32_alias = Alias("Float32", ty.f32());
auto* vec2_alias = Alias("VectorFloat2", ty.vec2<f32>());
- Global("my_f32", ty.Of(f32_alias), ast::StorageClass::kPrivate);
- Global("my_vec2", ty.Of(vec2_alias), ast::StorageClass::kPrivate);
+ GlobalVar("my_f32", ty.Of(f32_alias), ast::StorageClass::kPrivate);
+ GlobalVar("my_vec2", ty.Of(vec2_alias), ast::StorageClass::kPrivate);
auto* tc = vec3<f32>("my_vec2", "my_f32");
WrapInFunction(tc);
@@ -1661,11 +1854,14 @@
}
TEST_F(ResolverTypeConstructorValidationTest, InferVec2ElementTypeFromScalars) {
- auto* vec2_bool = Construct(create<ast::Vector>(nullptr, 2), Expr(true), Expr(false));
- auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2), Expr(1_i), Expr(2_i));
- auto* vec2_u32 = Construct(create<ast::Vector>(nullptr, 2), Expr(1_u), Expr(2_u));
- auto* vec2_f32 = Construct(create<ast::Vector>(nullptr, 2), Expr(1_f), Expr(2_f));
- WrapInFunction(vec2_bool, vec2_i32, vec2_u32, vec2_f32);
+ Enable(ast::Extension::kF16);
+
+ auto* vec2_bool = Construct(create<ast::Vector>(nullptr, 2u), Expr(true), Expr(false));
+ auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2u), Expr(1_i), Expr(2_i));
+ auto* vec2_u32 = Construct(create<ast::Vector>(nullptr, 2u), Expr(1_u), Expr(2_u));
+ auto* vec2_f32 = Construct(create<ast::Vector>(nullptr, 2u), Expr(1_f), Expr(2_f));
+ auto* vec2_f16 = Construct(create<ast::Vector>(nullptr, 2u), Expr(1_h), Expr(2_h));
+ WrapInFunction(vec2_bool, vec2_i32, vec2_u32, vec2_f32, vec2_f16);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1673,26 +1869,33 @@
ASSERT_TRUE(TypeOf(vec2_i32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec2_u32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec2_f32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(vec2_f16)->Is<sem::Vector>());
EXPECT_TRUE(TypeOf(vec2_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_TRUE(TypeOf(vec2_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_TRUE(TypeOf(vec2_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_TRUE(TypeOf(vec2_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(vec2_f16)->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(TypeOf(vec2_bool)->As<sem::Vector>()->Width(), 2u);
EXPECT_EQ(TypeOf(vec2_i32)->As<sem::Vector>()->Width(), 2u);
EXPECT_EQ(TypeOf(vec2_u32)->As<sem::Vector>()->Width(), 2u);
EXPECT_EQ(TypeOf(vec2_f32)->As<sem::Vector>()->Width(), 2u);
+ EXPECT_EQ(TypeOf(vec2_f16)->As<sem::Vector>()->Width(), 2u);
EXPECT_EQ(TypeOf(vec2_bool), TypeOf(vec2_bool->target.type));
EXPECT_EQ(TypeOf(vec2_i32), TypeOf(vec2_i32->target.type));
EXPECT_EQ(TypeOf(vec2_u32), TypeOf(vec2_u32->target.type));
EXPECT_EQ(TypeOf(vec2_f32), TypeOf(vec2_f32->target.type));
+ EXPECT_EQ(TypeOf(vec2_f16), TypeOf(vec2_f16->target.type));
}
TEST_F(ResolverTypeConstructorValidationTest, InferVec2ElementTypeFromVec2) {
- auto* vec2_bool = Construct(create<ast::Vector>(nullptr, 2), vec2<bool>(true, false));
- auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2), vec2<i32>(1_i, 2_i));
- auto* vec2_u32 = Construct(create<ast::Vector>(nullptr, 2), vec2<u32>(1_u, 2_u));
- auto* vec2_f32 = Construct(create<ast::Vector>(nullptr, 2), vec2<f32>(1_f, 2_f));
- WrapInFunction(vec2_bool, vec2_i32, vec2_u32, vec2_f32);
+ Enable(ast::Extension::kF16);
+
+ auto* vec2_bool = Construct(create<ast::Vector>(nullptr, 2u), vec2<bool>(true, false));
+ auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2u), vec2<i32>(1_i, 2_i));
+ auto* vec2_u32 = Construct(create<ast::Vector>(nullptr, 2u), vec2<u32>(1_u, 2_u));
+ auto* vec2_f32 = Construct(create<ast::Vector>(nullptr, 2u), vec2<f32>(1_f, 2_f));
+ auto* vec2_f16 = Construct(create<ast::Vector>(nullptr, 2u), vec2<f16>(1_h, 2_h));
+ WrapInFunction(vec2_bool, vec2_i32, vec2_u32, vec2_f32, vec2_f16);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1700,27 +1903,34 @@
ASSERT_TRUE(TypeOf(vec2_i32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec2_u32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec2_f32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(vec2_f16)->Is<sem::Vector>());
EXPECT_TRUE(TypeOf(vec2_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_TRUE(TypeOf(vec2_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_TRUE(TypeOf(vec2_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_TRUE(TypeOf(vec2_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(vec2_f16)->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(TypeOf(vec2_bool)->As<sem::Vector>()->Width(), 2u);
EXPECT_EQ(TypeOf(vec2_i32)->As<sem::Vector>()->Width(), 2u);
EXPECT_EQ(TypeOf(vec2_u32)->As<sem::Vector>()->Width(), 2u);
EXPECT_EQ(TypeOf(vec2_f32)->As<sem::Vector>()->Width(), 2u);
+ EXPECT_EQ(TypeOf(vec2_f16)->As<sem::Vector>()->Width(), 2u);
EXPECT_EQ(TypeOf(vec2_bool), TypeOf(vec2_bool->target.type));
EXPECT_EQ(TypeOf(vec2_i32), TypeOf(vec2_i32->target.type));
EXPECT_EQ(TypeOf(vec2_u32), TypeOf(vec2_u32->target.type));
EXPECT_EQ(TypeOf(vec2_f32), TypeOf(vec2_f32->target.type));
+ EXPECT_EQ(TypeOf(vec2_f16), TypeOf(vec2_f16->target.type));
}
TEST_F(ResolverTypeConstructorValidationTest, InferVec3ElementTypeFromScalars) {
+ Enable(ast::Extension::kF16);
+
auto* vec3_bool =
- Construct(create<ast::Vector>(nullptr, 3), Expr(true), Expr(false), Expr(true));
- auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1_i), Expr(2_i), Expr(3_i));
- auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1_u), Expr(2_u), Expr(3_u));
- auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1_f), Expr(2_f), Expr(3_f));
- WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32);
+ Construct(create<ast::Vector>(nullptr, 3u), Expr(true), Expr(false), Expr(true));
+ auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_i), Expr(2_i), Expr(3_i));
+ auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_u), Expr(2_u), Expr(3_u));
+ auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_f), Expr(2_f), Expr(3_f));
+ auto* vec3_f16 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_h), Expr(2_h), Expr(3_h));
+ WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32, vec3_f16);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1728,26 +1938,33 @@
ASSERT_TRUE(TypeOf(vec3_i32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec3_u32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec3_f32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(vec3_f16)->Is<sem::Vector>());
EXPECT_TRUE(TypeOf(vec3_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_TRUE(TypeOf(vec3_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_TRUE(TypeOf(vec3_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_TRUE(TypeOf(vec3_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(vec3_f16)->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(TypeOf(vec3_bool)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_i32)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_u32)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_f32)->As<sem::Vector>()->Width(), 3u);
+ EXPECT_EQ(TypeOf(vec3_f16)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_bool), TypeOf(vec3_bool->target.type));
EXPECT_EQ(TypeOf(vec3_i32), TypeOf(vec3_i32->target.type));
EXPECT_EQ(TypeOf(vec3_u32), TypeOf(vec3_u32->target.type));
EXPECT_EQ(TypeOf(vec3_f32), TypeOf(vec3_f32->target.type));
+ EXPECT_EQ(TypeOf(vec3_f16), TypeOf(vec3_f16->target.type));
}
TEST_F(ResolverTypeConstructorValidationTest, InferVec3ElementTypeFromVec3) {
- auto* vec3_bool = Construct(create<ast::Vector>(nullptr, 3), vec3<bool>(true, false, true));
- auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3), vec3<i32>(1_i, 2_i, 3_i));
- auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3), vec3<u32>(1_u, 2_u, 3_u));
- auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3), vec3<f32>(1_f, 2_f, 3_f));
- WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32);
+ Enable(ast::Extension::kF16);
+
+ auto* vec3_bool = Construct(create<ast::Vector>(nullptr, 3u), vec3<bool>(true, false, true));
+ auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3u), vec3<i32>(1_i, 2_i, 3_i));
+ auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3u), vec3<u32>(1_u, 2_u, 3_u));
+ auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3u), vec3<f32>(1_f, 2_f, 3_f));
+ auto* vec3_f16 = Construct(create<ast::Vector>(nullptr, 3u), vec3<f16>(1_h, 2_h, 3_h));
+ WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32, vec3_f16);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1755,27 +1972,34 @@
ASSERT_TRUE(TypeOf(vec3_i32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec3_u32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec3_f32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(vec3_f16)->Is<sem::Vector>());
EXPECT_TRUE(TypeOf(vec3_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_TRUE(TypeOf(vec3_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_TRUE(TypeOf(vec3_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_TRUE(TypeOf(vec3_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(vec3_f16)->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(TypeOf(vec3_bool)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_i32)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_u32)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_f32)->As<sem::Vector>()->Width(), 3u);
+ EXPECT_EQ(TypeOf(vec3_f16)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_bool), TypeOf(vec3_bool->target.type));
EXPECT_EQ(TypeOf(vec3_i32), TypeOf(vec3_i32->target.type));
EXPECT_EQ(TypeOf(vec3_u32), TypeOf(vec3_u32->target.type));
EXPECT_EQ(TypeOf(vec3_f32), TypeOf(vec3_f32->target.type));
+ EXPECT_EQ(TypeOf(vec3_f16), TypeOf(vec3_f16->target.type));
}
TEST_F(ResolverTypeConstructorValidationTest, InferVec3ElementTypeFromScalarAndVec2) {
+ Enable(ast::Extension::kF16);
+
auto* vec3_bool =
- Construct(create<ast::Vector>(nullptr, 3), Expr(true), vec2<bool>(false, true));
- auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1_i), vec2<i32>(2_i, 3_i));
- auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1_u), vec2<u32>(2_u, 3_u));
- auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1_f), vec2<f32>(2_f, 3_f));
- WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32);
+ Construct(create<ast::Vector>(nullptr, 3u), Expr(true), vec2<bool>(false, true));
+ auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_i), vec2<i32>(2_i, 3_i));
+ auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_u), vec2<u32>(2_u, 3_u));
+ auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_f), vec2<f32>(2_f, 3_f));
+ auto* vec3_f16 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_h), vec2<f16>(2_h, 3_h));
+ WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32, vec3_f16);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1783,30 +2007,38 @@
ASSERT_TRUE(TypeOf(vec3_i32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec3_u32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec3_f32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(vec3_f16)->Is<sem::Vector>());
EXPECT_TRUE(TypeOf(vec3_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_TRUE(TypeOf(vec3_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_TRUE(TypeOf(vec3_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_TRUE(TypeOf(vec3_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(vec3_f16)->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(TypeOf(vec3_bool)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_i32)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_u32)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_f32)->As<sem::Vector>()->Width(), 3u);
+ EXPECT_EQ(TypeOf(vec3_f16)->As<sem::Vector>()->Width(), 3u);
EXPECT_EQ(TypeOf(vec3_bool), TypeOf(vec3_bool->target.type));
EXPECT_EQ(TypeOf(vec3_i32), TypeOf(vec3_i32->target.type));
EXPECT_EQ(TypeOf(vec3_u32), TypeOf(vec3_u32->target.type));
EXPECT_EQ(TypeOf(vec3_f32), TypeOf(vec3_f32->target.type));
+ EXPECT_EQ(TypeOf(vec3_f16), TypeOf(vec3_f16->target.type));
}
TEST_F(ResolverTypeConstructorValidationTest, InferVec4ElementTypeFromScalars) {
- auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4), Expr(true), Expr(false),
+ Enable(ast::Extension::kF16);
+
+ auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4u), Expr(true), Expr(false),
Expr(true), Expr(false));
auto* vec4_i32 =
- Construct(create<ast::Vector>(nullptr, 4), Expr(1_i), Expr(2_i), Expr(3_i), Expr(4_i));
+ Construct(create<ast::Vector>(nullptr, 4u), Expr(1_i), Expr(2_i), Expr(3_i), Expr(4_i));
auto* vec4_u32 =
- Construct(create<ast::Vector>(nullptr, 4), Expr(1_u), Expr(2_u), Expr(3_u), Expr(4_u));
+ Construct(create<ast::Vector>(nullptr, 4u), Expr(1_u), Expr(2_u), Expr(3_u), Expr(4_u));
auto* vec4_f32 =
- Construct(create<ast::Vector>(nullptr, 4), Expr(1_f), Expr(2_f), Expr(3_f), Expr(4_f));
- WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
+ Construct(create<ast::Vector>(nullptr, 4u), Expr(1_f), Expr(2_f), Expr(3_f), Expr(4_f));
+ auto* vec4_f16 =
+ Construct(create<ast::Vector>(nullptr, 4u), Expr(1_h), Expr(2_h), Expr(3_h), Expr(4_h));
+ WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32, vec4_f16);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1814,27 +2046,34 @@
ASSERT_TRUE(TypeOf(vec4_i32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec4_u32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec4_f32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(vec4_f16)->Is<sem::Vector>());
EXPECT_TRUE(TypeOf(vec4_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_TRUE(TypeOf(vec4_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_TRUE(TypeOf(vec4_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_TRUE(TypeOf(vec4_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(vec4_f16)->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(TypeOf(vec4_bool)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_i32)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_u32)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_f32)->As<sem::Vector>()->Width(), 4u);
+ EXPECT_EQ(TypeOf(vec4_f16)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_bool), TypeOf(vec4_bool->target.type));
EXPECT_EQ(TypeOf(vec4_i32), TypeOf(vec4_i32->target.type));
EXPECT_EQ(TypeOf(vec4_u32), TypeOf(vec4_u32->target.type));
EXPECT_EQ(TypeOf(vec4_f32), TypeOf(vec4_f32->target.type));
+ EXPECT_EQ(TypeOf(vec4_f16), TypeOf(vec4_f16->target.type));
}
TEST_F(ResolverTypeConstructorValidationTest, InferVec4ElementTypeFromVec4) {
+ Enable(ast::Extension::kF16);
+
auto* vec4_bool =
- Construct(create<ast::Vector>(nullptr, 4), vec4<bool>(true, false, true, false));
- auto* vec4_i32 = Construct(create<ast::Vector>(nullptr, 4), vec4<i32>(1_i, 2_i, 3_i, 4_i));
- auto* vec4_u32 = Construct(create<ast::Vector>(nullptr, 4), vec4<u32>(1_u, 2_u, 3_u, 4_u));
- auto* vec4_f32 = Construct(create<ast::Vector>(nullptr, 4), vec4<f32>(1_f, 2_f, 3_f, 4_f));
- WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
+ Construct(create<ast::Vector>(nullptr, 4u), vec4<bool>(true, false, true, false));
+ auto* vec4_i32 = Construct(create<ast::Vector>(nullptr, 4u), vec4<i32>(1_i, 2_i, 3_i, 4_i));
+ auto* vec4_u32 = Construct(create<ast::Vector>(nullptr, 4u), vec4<u32>(1_u, 2_u, 3_u, 4_u));
+ auto* vec4_f32 = Construct(create<ast::Vector>(nullptr, 4u), vec4<f32>(1_f, 2_f, 3_f, 4_f));
+ auto* vec4_f16 = Construct(create<ast::Vector>(nullptr, 4u), vec4<f16>(1_h, 2_h, 3_h, 4_h));
+ WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32, vec4_f16);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1842,30 +2081,38 @@
ASSERT_TRUE(TypeOf(vec4_i32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec4_u32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec4_f32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(vec4_f16)->Is<sem::Vector>());
EXPECT_TRUE(TypeOf(vec4_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_TRUE(TypeOf(vec4_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_TRUE(TypeOf(vec4_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_TRUE(TypeOf(vec4_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(vec4_f16)->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(TypeOf(vec4_bool)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_i32)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_u32)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_f32)->As<sem::Vector>()->Width(), 4u);
+ EXPECT_EQ(TypeOf(vec4_f16)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_bool), TypeOf(vec4_bool->target.type));
EXPECT_EQ(TypeOf(vec4_i32), TypeOf(vec4_i32->target.type));
EXPECT_EQ(TypeOf(vec4_u32), TypeOf(vec4_u32->target.type));
EXPECT_EQ(TypeOf(vec4_f32), TypeOf(vec4_f32->target.type));
+ EXPECT_EQ(TypeOf(vec4_f16), TypeOf(vec4_f16->target.type));
}
TEST_F(ResolverTypeConstructorValidationTest, InferVec4ElementTypeFromScalarAndVec3) {
+ Enable(ast::Extension::kF16);
+
auto* vec4_bool =
- Construct(create<ast::Vector>(nullptr, 4), Expr(true), vec3<bool>(false, true, false));
+ Construct(create<ast::Vector>(nullptr, 4u), Expr(true), vec3<bool>(false, true, false));
auto* vec4_i32 =
- Construct(create<ast::Vector>(nullptr, 4), Expr(1_i), vec3<i32>(2_i, 3_i, 4_i));
+ Construct(create<ast::Vector>(nullptr, 4u), Expr(1_i), vec3<i32>(2_i, 3_i, 4_i));
auto* vec4_u32 =
- Construct(create<ast::Vector>(nullptr, 4), Expr(1_u), vec3<u32>(2_u, 3_u, 4_u));
+ Construct(create<ast::Vector>(nullptr, 4u), Expr(1_u), vec3<u32>(2_u, 3_u, 4_u));
auto* vec4_f32 =
- Construct(create<ast::Vector>(nullptr, 4), Expr(1_f), vec3<f32>(2_f, 3_f, 4_f));
- WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
+ Construct(create<ast::Vector>(nullptr, 4u), Expr(1_f), vec3<f32>(2_f, 3_f, 4_f));
+ auto* vec4_f16 =
+ Construct(create<ast::Vector>(nullptr, 4u), Expr(1_h), vec3<f16>(2_h, 3_h, 4_h));
+ WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32, vec4_f16);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1873,30 +2120,38 @@
ASSERT_TRUE(TypeOf(vec4_i32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec4_u32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec4_f32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(vec4_f16)->Is<sem::Vector>());
EXPECT_TRUE(TypeOf(vec4_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_TRUE(TypeOf(vec4_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_TRUE(TypeOf(vec4_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_TRUE(TypeOf(vec4_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(vec4_f16)->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(TypeOf(vec4_bool)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_i32)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_u32)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_f32)->As<sem::Vector>()->Width(), 4u);
+ EXPECT_EQ(TypeOf(vec4_f16)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_bool), TypeOf(vec4_bool->target.type));
EXPECT_EQ(TypeOf(vec4_i32), TypeOf(vec4_i32->target.type));
EXPECT_EQ(TypeOf(vec4_u32), TypeOf(vec4_u32->target.type));
EXPECT_EQ(TypeOf(vec4_f32), TypeOf(vec4_f32->target.type));
+ EXPECT_EQ(TypeOf(vec4_f16), TypeOf(vec4_f16->target.type));
}
TEST_F(ResolverTypeConstructorValidationTest, InferVec4ElementTypeFromVec2AndVec2) {
- auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4), vec2<bool>(true, false),
+ Enable(ast::Extension::kF16);
+
+ auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4u), vec2<bool>(true, false),
vec2<bool>(true, false));
auto* vec4_i32 =
- Construct(create<ast::Vector>(nullptr, 4), vec2<i32>(1_i, 2_i), vec2<i32>(3_i, 4_i));
+ Construct(create<ast::Vector>(nullptr, 4u), vec2<i32>(1_i, 2_i), vec2<i32>(3_i, 4_i));
auto* vec4_u32 =
- Construct(create<ast::Vector>(nullptr, 4), vec2<u32>(1_u, 2_u), vec2<u32>(3_u, 4_u));
+ Construct(create<ast::Vector>(nullptr, 4u), vec2<u32>(1_u, 2_u), vec2<u32>(3_u, 4_u));
auto* vec4_f32 =
- Construct(create<ast::Vector>(nullptr, 4), vec2<f32>(1_f, 2_f), vec2<f32>(3_f, 4_f));
- WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
+ Construct(create<ast::Vector>(nullptr, 4u), vec2<f32>(1_f, 2_f), vec2<f32>(3_f, 4_f));
+ auto* vec4_f16 =
+ Construct(create<ast::Vector>(nullptr, 4u), vec2<f16>(1_h, 2_h), vec2<f16>(3_h, 4_h));
+ WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32, vec4_f16);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1904,29 +2159,33 @@
ASSERT_TRUE(TypeOf(vec4_i32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec4_u32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(vec4_f32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(vec4_f16)->Is<sem::Vector>());
EXPECT_TRUE(TypeOf(vec4_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_TRUE(TypeOf(vec4_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_TRUE(TypeOf(vec4_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_TRUE(TypeOf(vec4_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(vec4_f16)->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(TypeOf(vec4_bool)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_i32)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_u32)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_f32)->As<sem::Vector>()->Width(), 4u);
+ EXPECT_EQ(TypeOf(vec4_f16)->As<sem::Vector>()->Width(), 4u);
EXPECT_EQ(TypeOf(vec4_bool), TypeOf(vec4_bool->target.type));
EXPECT_EQ(TypeOf(vec4_i32), TypeOf(vec4_i32->target.type));
EXPECT_EQ(TypeOf(vec4_u32), TypeOf(vec4_u32->target.type));
EXPECT_EQ(TypeOf(vec4_f32), TypeOf(vec4_f32->target.type));
+ EXPECT_EQ(TypeOf(vec4_f16), TypeOf(vec4_f16->target.type));
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVectorElementTypeWithoutArgs) {
- WrapInFunction(Construct(Source{{12, 34}}, create<ast::Vector>(nullptr, 3)));
+ WrapInFunction(Construct(Source{{12, 34}}, create<ast::Vector>(nullptr, 3u)));
EXPECT_FALSE(r()->Resolve());
EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for vec3()"));
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec2ElementTypeFromScalarsMismatch) {
- WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 2),
+ WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 2u),
Expr(Source{{1, 2}}, 1_i), //
Expr(Source{{1, 3}}, 2_u)));
@@ -1935,7 +2194,7 @@
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec3ElementTypeFromScalarsMismatch) {
- WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 3),
+ WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 3u),
Expr(Source{{1, 2}}, 1_i), //
Expr(Source{{1, 3}}, 2_u), //
Expr(Source{{1, 4}}, 3_i)));
@@ -1946,7 +2205,7 @@
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec3ElementTypeFromScalarAndVec2Mismatch) {
- WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 3),
+ WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 3u),
Expr(Source{{1, 2}}, 1_i), //
Construct(Source{{1, 3}}, ty.vec2<f32>(), 2_f, 3_f)));
@@ -1956,7 +2215,7 @@
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec4ElementTypeFromScalarsMismatch) {
- WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4),
+ WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4u),
Expr(Source{{1, 2}}, 1_i), //
Expr(Source{{1, 3}}, 2_i), //
Expr(Source{{1, 4}}, 3_f), //
@@ -1968,7 +2227,7 @@
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec4ElementTypeFromScalarAndVec3Mismatch) {
- WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4),
+ WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4u),
Expr(Source{{1, 2}}, 1_i), //
Construct(Source{{1, 3}}, ty.vec3<u32>(), 2_u, 3_u, 4_u)));
@@ -1978,7 +2237,7 @@
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec4ElementTypeFromVec2AndVec2Mismatch) {
- WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4),
+ WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4u),
Construct(Source{{1, 2}}, ty.vec2<i32>(), 3_i, 4_i), //
Construct(Source{{1, 3}}, ty.vec2<u32>(), 3_u, 4_u)));
@@ -1990,35 +2249,60 @@
} // namespace VectorConstructor
namespace MatrixConstructor {
-struct MatrixDimensions {
+
+struct MatrixParams {
+ using name_func_ptr = std::string (*)();
+
uint32_t rows;
uint32_t columns;
+ name_func_ptr get_element_type_name;
+ builder::ast_type_func_ptr create_element_ast_type;
+ builder::ast_expr_func_ptr create_element_ast_value;
+ builder::ast_type_func_ptr create_column_ast_type;
+ builder::ast_type_func_ptr create_mat_ast_type;
};
-static std::string MatrixStr(const MatrixDimensions& dimensions) {
- return "mat" + std::to_string(dimensions.columns) + "x" + std::to_string(dimensions.rows) +
- "<f32>";
+template <typename T, uint32_t R, uint32_t C>
+constexpr MatrixParams MatrixParamsFor() {
+ return MatrixParams{
+ R,
+ C,
+ DataType<T>::Name,
+ DataType<T>::AST,
+ DataType<T>::Expr,
+ DataType<tint::resolver::builder::vec<R, T>>::AST,
+ DataType<tint::resolver::builder::mat<C, R, T>>::AST,
+ };
}
-using MatrixConstructorTest = ResolverTestWithParam<MatrixDimensions>;
+static std::string MatrixStr(const MatrixParams& param) {
+ return "mat" + std::to_string(param.columns) + "x" + std::to_string(param.rows) + "<" +
+ param.get_element_type_name() + ">";
+}
+
+using MatrixConstructorTest = ResolverTestWithParam<MatrixParams>;
TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooFewArguments) {
// matNxM<f32>(vecM<f32>(), ...); with N - 1 arguments
+ // matNxM<f16>(vecM<f16>(), ...); with N - 1 arguments
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
+ const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns - 1; i++) {
- auto* vec_type = ty.vec<f32>(param.rows);
+ auto* vec_type = param.create_column_ast_type(*this);
args.push_back(Construct(vec_type));
if (i > 0) {
args_tys << ", ";
}
- args_tys << "vec" << param.rows << "<f32>";
+ args_tys << "vec" << param.rows << "<" + element_type_name + ">";
}
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2029,20 +2313,24 @@
TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_TooFewArguments) {
// matNxM<f32>(f32,...,f32); with N*M - 1 arguments
+ // matNxM<f16>(f16,...,f16); with N*M - 1 arguments
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
+ const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns * param.rows - 1; i++) {
- args.push_back(Construct(ty.f32()));
+ args.push_back(Construct(param.create_element_ast_type(*this)));
if (i > 0) {
args_tys << ", ";
}
- args_tys << "f32";
+ args_tys << element_type_name;
}
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2053,21 +2341,25 @@
TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooManyArguments) {
// matNxM<f32>(vecM<f32>(), ...); with N + 1 arguments
+ // matNxM<f16>(vecM<f16>(), ...); with N + 1 arguments
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
+ const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns + 1; i++) {
- auto* vec_type = ty.vec<f32>(param.rows);
+ auto* vec_type = param.create_column_ast_type(*this);
args.push_back(Construct(vec_type));
if (i > 0) {
args_tys << ", ";
}
- args_tys << "vec" << param.rows << "<f32>";
+ args_tys << "vec" << param.rows << "<" + element_type_name + ">";
}
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2078,20 +2370,24 @@
TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_TooManyArguments) {
// matNxM<f32>(f32,...,f32); with N*M + 1 arguments
+ // matNxM<f16>(f16,...,f16); with N*M + 1 arguments
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
+ const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns * param.rows + 1; i++) {
- args.push_back(Construct(ty.f32()));
+ args.push_back(Construct(param.create_element_ast_type(*this)));
if (i > 0) {
args_tys << ", ";
}
- args_tys << "f32";
+ args_tys << element_type_name;
}
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2102,9 +2398,12 @@
TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_InvalidArgumentType) {
// matNxM<f32>(vec<u32>, vec<u32>, ...); N arguments
+ // matNxM<f16>(vec<u32>, vec<u32>, ...); N arguments
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
std::stringstream args_tys;
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
@@ -2116,7 +2415,7 @@
args_tys << "vec" << param.rows << "<u32>";
}
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2127,9 +2426,12 @@
TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_InvalidArgumentType) {
// matNxM<f32>(u32, u32, ...); N*M arguments
+ // matNxM<f16>(u32, u32, ...); N*M arguments
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
std::stringstream args_tys;
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
@@ -2140,7 +2442,7 @@
args_tys << "u32";
}
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2151,6 +2453,7 @@
TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooFewRowsInVectorArgument) {
// matNxM<f32>(vecM<f32>(),...,vecM-1<f32>());
+ // matNxM<f16>(vecM<f16>(),...,vecM-1<f32>());
const auto param = GetParam();
@@ -2159,22 +2462,25 @@
return;
}
+ Enable(ast::Extension::kF16);
+
+ const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
- auto* valid_vec_type = ty.vec<f32>(param.rows);
+ auto* valid_vec_type = param.create_column_ast_type(*this);
args.push_back(Construct(valid_vec_type));
if (i > 0) {
args_tys << ", ";
}
- args_tys << "vec" << param.rows << "<f32>";
+ args_tys << "vec" << param.rows << "<" + element_type_name + ">";
}
const size_t kInvalidLoc = 2 * (param.columns - 1);
- auto* invalid_vec_type = ty.vec<f32>(param.rows - 1);
+ auto* invalid_vec_type = ty.vec(param.create_element_ast_type(*this), param.rows - 1);
args.push_back(Construct(Source{{12, kInvalidLoc}}, invalid_vec_type));
- args_tys << ", vec" << (param.rows - 1) << "<f32>";
+ args_tys << ", vec" << (param.rows - 1) << "<" + element_type_name + ">";
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2185,6 +2491,7 @@
TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooManyRowsInVectorArgument) {
// matNxM<f32>(vecM<f32>(),...,vecM+1<f32>());
+ // matNxM<f16>(vecM<f16>(),...,vecM+1<f16>());
const auto param = GetParam();
@@ -2193,21 +2500,24 @@
return;
}
+ Enable(ast::Extension::kF16);
+
+ const std::string element_type_name = param.get_element_type_name();
std::stringstream args_tys;
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
- auto* valid_vec_type = ty.vec<f32>(param.rows);
+ auto* valid_vec_type = param.create_column_ast_type(*this);
args.push_back(Construct(valid_vec_type));
if (i > 0) {
args_tys << ", ";
}
- args_tys << "vec" << param.rows << "<f32>";
+ args_tys << "vec" << param.rows << "<" + element_type_name + ">";
}
- auto* invalid_vec_type = ty.vec<f32>(param.rows + 1);
+ auto* invalid_vec_type = ty.vec(param.create_element_ast_type(*this), param.rows + 1);
args.push_back(Construct(invalid_vec_type));
- args_tys << ", vec" << (param.rows + 1) << "<f32>";
+ args_tys << ", vec" << (param.rows + 1) << "<" + element_type_name + ">";
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2218,9 +2528,13 @@
TEST_P(MatrixConstructorTest, Expr_Constructor_ZeroValue_Success) {
// matNxM<f32>();
+ // matNxM<f16>();
const auto param = GetParam();
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+
+ Enable(ast::Extension::kF16);
+
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(Source{{12, 40}}, matrix_type);
WrapInFunction(tc);
@@ -2229,16 +2543,19 @@
TEST_P(MatrixConstructorTest, Expr_Constructor_WithColumns_Success) {
// matNxM<f32>(vecM<f32>(), ...); with N arguments
+ // matNxM<f16>(vecM<f16>(), ...); with N arguments
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
- auto* vec_type = ty.vec<f32>(param.rows);
+ auto* vec_type = param.create_column_ast_type(*this);
args.push_back(Construct(vec_type));
}
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2247,15 +2564,18 @@
TEST_P(MatrixConstructorTest, Expr_Constructor_WithElements_Success) {
// matNxM<f32>(f32,...,f32); with N*M arguments
+ // matNxM<f16>(f16,...,f16); with N*M arguments
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns * param.rows; i++) {
- args.push_back(Construct(ty.f32()));
+ args.push_back(Construct(param.create_element_ast_type(*this)));
}
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2264,9 +2584,13 @@
TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Error) {
// matNxM<Float32>(vecM<u32>(), ...); with N arguments
+ // matNxM<Float16>(vecM<u32>(), ...); with N arguments
const auto param = GetParam();
- auto* f32_alias = Alias("Float32", ty.f32());
+
+ Enable(ast::Extension::kF16);
+
+ auto* elem_type_alias = Alias("ElemType", param.create_element_ast_type(*this));
std::stringstream args_tys;
ast::ExpressionList args;
@@ -2279,7 +2603,7 @@
args_tys << "vec" << param.rows << "<u32>";
}
- auto* matrix_type = ty.mat(ty.Of(f32_alias), param.columns, param.rows);
+ auto* matrix_type = ty.mat(ty.Of(elem_type_alias), param.columns, param.rows);
auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2290,17 +2614,21 @@
TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Success) {
// matNxM<Float32>(vecM<f32>(), ...); with N arguments
+ // matNxM<Float16>(vecM<f16>(), ...); with N arguments
const auto param = GetParam();
- auto* f32_alias = Alias("Float32", ty.f32());
+
+ Enable(ast::Extension::kF16);
+
+ auto* elem_type_alias = Alias("ElemType", param.create_element_ast_type(*this));
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
- auto* vec_type = ty.vec<f32>(param.rows);
+ auto* vec_type = param.create_column_ast_type(*this);
args.push_back(Construct(vec_type));
}
- auto* matrix_type = ty.mat(ty.Of(f32_alias), param.columns, param.rows);
+ auto* matrix_type = ty.mat(ty.Of(elem_type_alias), param.columns, param.rows);
auto* tc = Construct(Source{}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2320,9 +2648,12 @@
TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentTypeAlias_Success) {
const auto param = GetParam();
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* vec_type = ty.vec<f32>(param.rows);
- auto* vec_alias = Alias("VectorFloat2", vec_type);
+
+ Enable(ast::Extension::kF16);
+
+ auto* matrix_type = param.create_mat_ast_type(*this);
+ auto* vec_type = param.create_column_ast_type(*this);
+ auto* vec_alias = Alias("ColVectorAlias", vec_type);
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
@@ -2337,13 +2668,16 @@
TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Error) {
const auto param = GetParam();
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* f32_alias = Alias("UnsignedInt", ty.u32());
+
+ Enable(ast::Extension::kF16);
+
+ auto* matrix_type = param.create_mat_ast_type(*this);
+ auto* u32_type_alias = Alias("UnsignedInt", ty.u32());
std::stringstream args_tys;
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
- auto* vec_type = ty.vec(ty.Of(f32_alias), param.rows);
+ auto* vec_type = ty.vec(ty.Of(u32_type_alias), param.rows);
args.push_back(Construct(vec_type));
if (i > 0) {
args_tys << ", ";
@@ -2361,15 +2695,18 @@
TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Success) {
const auto param = GetParam();
- auto* f32_alias = Alias("Float32", ty.f32());
+
+ Enable(ast::Extension::kF16);
+
+ auto* elem_type_alias = Alias("ElemType", param.create_element_ast_type(*this));
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
- auto* vec_type = ty.vec(ty.Of(f32_alias), param.rows);
+ auto* vec_type = ty.vec(ty.Of(elem_type_alias), param.rows);
args.push_back(Construct(vec_type));
}
- auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
+ auto* matrix_type = param.create_mat_ast_type(*this);
auto* tc = Construct(Source{}, matrix_type, std::move(args));
WrapInFunction(tc);
@@ -2379,9 +2716,11 @@
TEST_P(MatrixConstructorTest, InferElementTypeFromVectors) {
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
- args.push_back(Construct(ty.vec<f32>(param.rows)));
+ args.push_back(Construct(param.create_column_ast_type(*this)));
}
auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
@@ -2394,9 +2733,11 @@
TEST_P(MatrixConstructorTest, InferElementTypeFromScalars) {
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
ast::ExpressionList args;
for (uint32_t i = 0; i < param.rows * param.columns; i++) {
- args.push_back(Expr(static_cast<f32>(i)));
+ args.push_back(param.create_element_ast_value(*this, static_cast<double>(i)));
}
auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
@@ -2408,6 +2749,8 @@
TEST_P(MatrixConstructorTest, CannotInferElementTypeFromVectors_Mismatch) {
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
std::stringstream err;
err << "12:34 error: no matching constructor for mat" << param.columns << "x" << param.rows
<< "(";
@@ -2422,8 +2765,8 @@
args.push_back(Construct(ty.vec<i32>(param.rows)));
err << "vec" << param.rows << "<i32>";
} else {
- args.push_back(Construct(ty.vec<f32>(param.rows)));
- err << "vec" << param.rows << "<f32>";
+ args.push_back(Construct(param.create_column_ast_type(*this)));
+ err << "vec" << param.rows << "<" + param.get_element_type_name() + ">";
}
}
@@ -2437,6 +2780,8 @@
TEST_P(MatrixConstructorTest, CannotInferElementTypeFromScalars_Mismatch) {
const auto param = GetParam();
+ Enable(ast::Extension::kF16);
+
std::stringstream err;
err << "12:34 error: no matching constructor for mat" << param.columns << "x" << param.rows
<< "(";
@@ -2450,8 +2795,8 @@
args.push_back(Expr(static_cast<i32>(i))); // The odd one out
err << "i32";
} else {
- args.push_back(Expr(static_cast<f32>(i)));
- err << "f32";
+ args.push_back(param.create_element_ast_value(*this, static_cast<double>(i)));
+ err << param.get_element_type_name();
}
}
@@ -2466,15 +2811,24 @@
INSTANTIATE_TEST_SUITE_P(ResolverTypeConstructorValidationTest,
MatrixConstructorTest,
- testing::Values(MatrixDimensions{2, 2},
- MatrixDimensions{3, 2},
- MatrixDimensions{4, 2},
- MatrixDimensions{2, 3},
- MatrixDimensions{3, 3},
- MatrixDimensions{4, 3},
- MatrixDimensions{2, 4},
- MatrixDimensions{3, 4},
- MatrixDimensions{4, 4}));
+ testing::Values(MatrixParamsFor<f32, 2, 2>(),
+ MatrixParamsFor<f32, 3, 2>(),
+ MatrixParamsFor<f32, 4, 2>(),
+ MatrixParamsFor<f32, 2, 3>(),
+ MatrixParamsFor<f32, 3, 3>(),
+ MatrixParamsFor<f32, 4, 3>(),
+ MatrixParamsFor<f32, 2, 4>(),
+ MatrixParamsFor<f32, 3, 4>(),
+ MatrixParamsFor<f32, 4, 4>(),
+ MatrixParamsFor<f16, 2, 2>(),
+ MatrixParamsFor<f16, 3, 2>(),
+ MatrixParamsFor<f16, 4, 2>(),
+ MatrixParamsFor<f16, 2, 3>(),
+ MatrixParamsFor<f16, 3, 3>(),
+ MatrixParamsFor<f16, 4, 3>(),
+ MatrixParamsFor<f16, 2, 4>(),
+ MatrixParamsFor<f16, 3, 4>(),
+ MatrixParamsFor<f16, 4, 4>()));
} // namespace MatrixConstructor
namespace StructConstructor {
@@ -2492,13 +2846,18 @@
CreatePtrsFor<u32>(), //
CreatePtrsFor<i32>(), //
CreatePtrsFor<f32>(), //
+ CreatePtrsFor<f16>(), //
CreatePtrsFor<vec4<bool>>(), //
CreatePtrsFor<vec2<i32>>(), //
CreatePtrsFor<vec3<u32>>(), //
CreatePtrsFor<vec4<f32>>(), //
+ CreatePtrsFor<vec4<f16>>(), //
CreatePtrsFor<mat2x2<f32>>(), //
CreatePtrsFor<mat3x3<f32>>(), //
- CreatePtrsFor<mat4x4<f32>>() //
+ CreatePtrsFor<mat4x4<f32>>(), //
+ CreatePtrsFor<mat2x2<f16>>(), //
+ CreatePtrsFor<mat3x3<f16>>(), //
+ CreatePtrsFor<mat4x4<f16>>() //
};
auto number_of_members = testing::Values(2u, 32u, 64u);
@@ -2511,6 +2870,8 @@
auto& str_params = std::get<0>(param);
uint32_t N = std::get<1>(param);
+ Enable(ast::Extension::kF16);
+
ast::StructMemberList members;
ast::ExpressionList values;
for (uint32_t i = 0; i < N; i++) {
@@ -2534,6 +2895,8 @@
auto& str_params = std::get<0>(param);
uint32_t N = std::get<1>(param);
+ Enable(ast::Extension::kF16);
+
ast::StructMemberList members;
ast::ExpressionList values;
for (uint32_t i = 0; i < N + 1; i++) {
@@ -2565,6 +2928,8 @@
auto& ctor_params = std::get<1>(param);
uint32_t N = std::get<2>(param);
+ Enable(ast::Extension::kF16);
+
if (str_params.ast == ctor_params.ast) {
return;
}
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index ec2f8f5..e746e51 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -82,14 +82,14 @@
TEST_F(ResolverTypeValidationTest, GlobalVariableWithStorageClass_Pass) {
// var<private> global_var: f32;
- Global(Source{{12, 34}}, "global_var", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{12, 34}}, "global_var", ty.f32(), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverTypeValidationTest, GlobalConstNoStorageClass_Pass) {
- // let global_var: f32;
- GlobalConst(Source{{12, 34}}, "global_var", ty.f32(), Construct(ty.f32()));
+ // const global_const: f32 = f32();
+ GlobalConst(Source{{12, 34}}, "global_const", ty.f32(), Construct(ty.f32()));
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -98,9 +98,9 @@
// var global_var0 : f32 = 0.1;
// var global_var1 : i32 = 0;
- Global("global_var0", ty.f32(), ast::StorageClass::kPrivate, Expr(0.1_f));
+ GlobalVar("global_var0", ty.f32(), ast::StorageClass::kPrivate, Expr(0.1_f));
- Global(Source{{12, 34}}, "global_var1", ty.f32(), ast::StorageClass::kPrivate, Expr(1_f));
+ GlobalVar(Source{{12, 34}}, "global_var1", ty.f32(), ast::StorageClass::kPrivate, Expr(1_f));
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -116,7 +116,7 @@
Decl(Var("a", ty.f32(), ast::StorageClass::kNone, Expr(2_f))),
});
- Global("a", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -180,162 +180,181 @@
TEST_F(ResolverTypeValidationTest, ArraySize_AIntLiteral_Pass) {
// var<private> a : array<f32, 4>;
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_a)), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_a)), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Pass) {
// var<private> a : array<f32, 4u>;
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_u)), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_u)), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Pass) {
// var<private> a : array<f32, 4i>;
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_i)), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_i)), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLet_Pass) {
- // let size = 4u;
+TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedConst_Pass) {
+ // const size = 4u;
// var<private> a : array<f32, size>;
GlobalConst("size", nullptr, Expr(4_u));
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Pass) {
- // let size = 4i;
+TEST_F(ResolverTypeValidationTest, ArraySize_SignedConst_Pass) {
+ // const size = 4i;
// var<private> a : array<f32, size>;
GlobalConst("size", nullptr, Expr(4_i));
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverTypeValidationTest, ArraySize_AIntLiteral_Zero) {
// var<private> a : array<f32, 0>;
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_a)), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_a)), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+ EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
}
TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Zero) {
// var<private> a : array<f32, 0u>;
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_u)), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_u)), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+ EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
}
TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Zero) {
// var<private> a : array<f32, 0i>;
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_i)), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_i)), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+ EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
}
TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Negative) {
// var<private> a : array<f32, -10i>;
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, -10_i)), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, -10_i)), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+ EXPECT_EQ(r()->error(), "12:34 error: array size (-10) must be greater than 0");
}
-TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLet_Zero) {
- // let size = 0u;
+TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedConst_Zero) {
+ // const size = 0u;
// var<private> a : array<f32, size>;
GlobalConst("size", nullptr, Expr(0_u));
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+ EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
}
-TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Zero) {
- // let size = 0i;
+TEST_F(ResolverTypeValidationTest, ArraySize_SignedConst_Zero) {
+ // const size = 0i;
// var<private> a : array<f32, size>;
GlobalConst("size", nullptr, Expr(0_i));
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+ EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
}
-TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Negative) {
- // let size = -10i;
+TEST_F(ResolverTypeValidationTest, ArraySize_SignedConst_Negative) {
+ // const size = -10i;
// var<private> a : array<f32, size>;
GlobalConst("size", nullptr, Expr(-10_i));
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+ EXPECT_EQ(r()->error(), "12:34 error: array size (-10) must be greater than 0");
}
TEST_F(ResolverTypeValidationTest, ArraySize_FloatLiteral) {
// var<private> a : array<f32, 10.0>;
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 10_f)), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 10_f)), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
+ EXPECT_EQ(r()->error(),
+ "12:34 error: array size must evaluate to a constant integer expression, but is type "
+ "'f32'");
}
TEST_F(ResolverTypeValidationTest, ArraySize_IVecLiteral) {
// var<private> a : array<f32, vec2<i32>(10, 10)>;
- Global("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.vec2<i32>(), 10_i, 10_i)),
- ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.vec2<i32>(), 10_i, 10_i)),
+ ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
+ EXPECT_EQ(r()->error(),
+ "12:34 error: array size must evaluate to a constant integer expression, but is type "
+ "'vec2<i32>'");
}
-TEST_F(ResolverTypeValidationTest, ArraySize_FloatLet) {
- // let size = 10.0;
+TEST_F(ResolverTypeValidationTest, ArraySize_FloatConst) {
+ // const size = 10.0;
// var<private> a : array<f32, size>;
GlobalConst("size", nullptr, Expr(10_f));
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
+ EXPECT_EQ(r()->error(),
+ "12:34 error: array size must evaluate to a constant integer expression, but is type "
+ "'f32'");
}
-TEST_F(ResolverTypeValidationTest, ArraySize_IVecLet) {
- // let size = vec2<i32>(100, 100);
+TEST_F(ResolverTypeValidationTest, ArraySize_IVecConst) {
+ // const size = vec2<i32>(100, 100);
// var<private> a : array<f32, size>;
GlobalConst("size", nullptr, Construct(ty.vec2<i32>(), 100_i, 100_i));
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
+ EXPECT_EQ(r()->error(),
+ "12:34 error: array size must evaluate to a constant integer expression, but is type "
+ "'vec2<i32>'");
}
TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ImplicitStride) {
// var<private> a : array<f32, 0x40000000u>;
- Global("a", ty.array(Source{{12, 34}}, ty.f32(), 0x40000000_u), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(Source{{12, 34}}, ty.f32(), 0x40000000_u), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array size in bytes must not exceed 0xffffffff, but "
- "is 0x100000000");
+ "12:34 error: array size (0x100000000) must not exceed 0xffffffff bytes");
}
TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ExplicitStride) {
// var<private> a : @stride(8) array<f32, 0x20000000u>;
- Global("a", ty.array(Source{{12, 34}}, ty.f32(), 0x20000000_u, 8), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(Source{{12, 34}}, ty.f32(), 0x20000000_u, 8),
+ ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array size in bytes must not exceed 0xffffffff, but "
- "is 0x100000000");
+ "12:34 error: array size (0x100000000) must not exceed 0xffffffff bytes");
}
TEST_F(ResolverTypeValidationTest, ArraySize_Overridable) {
// override size = 10i;
// var<private> a : array<f32, size>;
Override("size", nullptr, Expr(10_i));
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array size identifier must be a literal or a module-scope 'let'");
+ "12:34 error: array size must evaluate to a constant integer expression");
}
TEST_F(ResolverTypeValidationTest, ArraySize_ModuleVar) {
// var<private> size : i32 = 10i;
// var<private> a : array<f32, size>;
- Global("size", ty.i32(), Expr(10_i), ast::StorageClass::kPrivate);
- Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+ GlobalVar("size", ty.i32(), Expr(10_i), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array size identifier must be a literal or a module-scope 'let'");
+ R"(12:34 error: var 'size' cannot not be referenced at module-scope
+note: var 'size' declared here)");
+}
+
+TEST_F(ResolverTypeValidationTest, ArraySize_FunctionConst) {
+ // {
+ // const size = 10;
+ // var a : array<f32, size>;
+ // }
+ auto* size = Const("size", nullptr, Expr(10_i));
+ auto* a = Var("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")));
+ WrapInFunction(size, a);
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverTypeValidationTest, ArraySize_FunctionLet) {
@@ -345,19 +364,17 @@
// }
auto* size = Let("size", nullptr, Expr(10_i));
auto* a = Var("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")));
- WrapInFunction(Block(Decl(size), Decl(a)));
+ WrapInFunction(size, a);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array size identifier must be a literal or a module-scope 'let'");
+ "12:34 error: array size must evaluate to a constant integer expression");
}
-TEST_F(ResolverTypeValidationTest, ArraySize_InvalidExpr) {
+TEST_F(ResolverTypeValidationTest, ArraySize_ComplexExpr) {
// var a : array<f32, i32(4i)>;
auto* a = Var("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.i32(), 4_i)));
- WrapInFunction(Block(Decl(a)));
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: array size identifier must be a literal or a module-scope 'let'");
+ WrapInFunction(a);
+ EXPECT_TRUE(r()->Resolve());
}
TEST_F(ResolverTypeValidationTest, RuntimeArrayInFunction_Fail) {
@@ -377,7 +394,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
-12:34 note: while instantiating variable a)");
+12:34 note: while instantiating 'var' a)");
}
TEST_F(ResolverTypeValidationTest, Struct_Member_VectorNoType) {
@@ -385,7 +402,7 @@
// a: vec3;
// };
- Structure("S", {Member("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3))});
+ Structure("S", {Member("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3u))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
@@ -395,7 +412,7 @@
// struct S {
// a: mat3x3;
// };
- Structure("S", {Member("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3, 3))});
+ Structure("S", {Member("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3u, 3u))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
@@ -417,8 +434,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: struct size in bytes must not exceed 0xffffffff, but "
- "is 0x100000000");
+ "12:34 error: struct size (0x100000000) must not exceed 0xffffffff bytes");
}
TEST_F(ResolverTypeValidationTest, Struct_MemberOffset_TooBig) {
@@ -438,8 +454,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: struct member has byte offset 0x100000000, but must "
- "not exceed 0xffffffff");
+ "12:34 error: struct member offset (0x100000000) must not exceed 0xffffffff bytes");
}
TEST_F(ResolverTypeValidationTest, RuntimeArrayIsLast_Pass) {
@@ -467,8 +482,7 @@
EXPECT_FALSE(r()->Resolve()) << r()->error();
EXPECT_EQ(r()->error(),
- "12:34 error: an array element type cannot contain a runtime-sized "
- "array");
+ "12:34 error: an array element type cannot contain a runtime-sized array");
}
TEST_F(ResolverTypeValidationTest, RuntimeArrayInStructInArray) {
@@ -478,12 +492,11 @@
// var<private> a : array<Foo, 4>;
auto* foo = Structure("Foo", {Member("rt", ty.array<f32>())});
- Global("v", ty.array(Source{{12, 34}}, ty.Of(foo), 4_u), ast::StorageClass::kPrivate);
+ GlobalVar("v", ty.array(Source{{12, 34}}, ty.Of(foo), 4_u), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve()) << r()->error();
EXPECT_EQ(r()->error(),
- "12:34 error: an array element type cannot contain a runtime-sized "
- "array");
+ "12:34 error: an array element type cannot contain a runtime-sized array");
}
TEST_F(ResolverTypeValidationTest, RuntimeArrayInStructInStruct) {
@@ -499,8 +512,8 @@
EXPECT_FALSE(r()->Resolve()) << r()->error();
EXPECT_EQ(r()->error(),
- "12:34 error: a struct that contains a runtime array cannot be "
- "nested inside another struct");
+ "12:34 error: a struct that contains a runtime array cannot be nested inside another "
+ "struct");
}
TEST_F(ResolverTypeValidationTest, RuntimeArrayIsNotLast_Fail) {
@@ -522,13 +535,13 @@
}
TEST_F(ResolverTypeValidationTest, RuntimeArrayAsGlobalVariable) {
- Global(Source{{56, 78}}, "g", ty.array<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{56, 78}}, "g", ty.array<i32>(), ast::StorageClass::kPrivate);
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(56:78 error: runtime-sized arrays can only be used in the <storage> storage class
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverTypeValidationTest, RuntimeArrayAsLocalVariable) {
@@ -539,7 +552,7 @@
EXPECT_EQ(r()->error(),
R"(56:78 error: runtime-sized arrays can only be used in the <storage> storage class
-56:78 note: while instantiating variable g)");
+56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverTypeValidationTest, RuntimeArrayAsParameter_Fail) {
@@ -601,8 +614,7 @@
EXPECT_FALSE(r()->Resolve()) << r()->error();
EXPECT_EQ(r()->error(),
- "12:34 error: runtime arrays may only appear as the last member of "
- "a struct");
+ "12:34 error: runtime arrays may only appear as the last member of a struct");
}
TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsLast_Pass) {
@@ -625,19 +637,18 @@
TEST_F(ResolverTypeValidationTest, ArrayOfNonStorableType) {
auto* tex_ty = ty.sampled_texture(ast::TextureDimension::k2d, ty.f32());
- Global("arr", ty.array(Source{{12, 34}}, tex_ty, 4_i), ast::StorageClass::kPrivate);
+ GlobalVar("arr", ty.array(Source{{12, 34}}, tex_ty, 4_i), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: texture_2d<f32> cannot be used as an element type of "
- "an array");
+ "12:34 error: texture_2d<f32> cannot be used as an element type of an array");
}
TEST_F(ResolverTypeValidationTest, VariableAsType) {
// var<private> a : i32;
// var<private> b : a;
- Global("a", ty.i32(), ast::StorageClass::kPrivate);
- Global("b", ty.type_name("a"), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.type_name("a"), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -649,7 +660,7 @@
// fn f() {}
// var<private> v : f;
Func("f", {}, ty.void_(), {});
- Global("v", ty.type_name("f"), ast::StorageClass::kPrivate);
+ GlobalVar("v", ty.type_name("f"), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
@@ -659,7 +670,7 @@
TEST_F(ResolverTypeValidationTest, BuiltinAsType) {
// var<private> v : max;
- Global("v", ty.type_name("max"), ast::StorageClass::kPrivate);
+ GlobalVar("v", ty.type_name("max"), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "error: cannot use builtin 'max' as type");
@@ -670,14 +681,14 @@
// var<private> v : f16;
Enable(ast::Extension::kF16);
- Global("v", ty.f16(), ast::StorageClass::kPrivate);
+ GlobalVar("v", ty.f16(), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverTypeValidationTest, F16TypeUsedWithoutExtension) {
// var<private> v : f16;
- Global("v", ty.f16(), ast::StorageClass::kPrivate);
+ GlobalVar("v", ty.f16(), ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "error: f16 used without 'f16' extension enabled");
@@ -749,8 +760,8 @@
using SampledTextureDimensionTest = ResolverTestWithParam<DimensionParams>;
TEST_P(SampledTextureDimensionTest, All) {
auto& params = GetParam();
- Global(Source{{12, 34}}, "a", ty.sampled_texture(params.dim, ty.i32()),
- ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar(Source{{12, 34}}, "a", ty.sampled_texture(params.dim, ty.i32()),
+ ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -767,8 +778,8 @@
using MultisampledTextureDimensionTest = ResolverTestWithParam<DimensionParams>;
TEST_P(MultisampledTextureDimensionTest, All) {
auto& params = GetParam();
- Global("a", ty.multisampled_texture(Source{{12, 34}}, params.dim, ty.i32()),
- ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a", ty.multisampled_texture(Source{{12, 34}}, params.dim, ty.i32()),
+ ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -818,7 +829,7 @@
using SampledTextureTypeTest = ResolverTestWithParam<TypeParams>;
TEST_P(SampledTextureTypeTest, All) {
auto& params = GetParam();
- Global(
+ GlobalVar(
"a",
ty.sampled_texture(Source{{12, 34}}, ast::TextureDimension::k2d, params.type_func(*this)),
ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
@@ -837,10 +848,10 @@
using MultisampledTextureTypeTest = ResolverTestWithParam<TypeParams>;
TEST_P(MultisampledTextureTypeTest, All) {
auto& params = GetParam();
- Global("a",
- ty.multisampled_texture(Source{{12, 34}}, ast::TextureDimension::k2d,
- params.type_func(*this)),
- ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a",
+ ty.multisampled_texture(Source{{12, 34}}, ast::TextureDimension::k2d,
+ params.type_func(*this)),
+ ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -879,7 +890,7 @@
auto* st = ty.storage_texture(Source{{12, 34}}, params.dim, ast::TexelFormat::kR32Uint,
ast::Access::kWrite);
- Global("a", st, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a", st, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 0)});
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -929,17 +940,17 @@
auto* st_a = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d, params.format,
ast::Access::kWrite);
- Global("a", st_a, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a", st_a, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 0)});
auto* st_b = ty.storage_texture(ast::TextureDimension::k2d, params.format, ast::Access::kWrite);
- Global("b", st_b, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 1)});
+ GlobalVar("b", st_b, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 1)});
auto* st_c =
ty.storage_texture(ast::TextureDimension::k2dArray, params.format, ast::Access::kWrite);
- Global("c", st_c, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 2)});
+ GlobalVar("c", st_c, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 2)});
auto* st_d = ty.storage_texture(ast::TextureDimension::k3d, params.format, ast::Access::kWrite);
- Global("d", st_d, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 3)});
+ GlobalVar("d", st_d, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 3)});
if (params.is_valid) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -963,7 +974,7 @@
auto* st = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d,
ast::TexelFormat::kR32Uint, ast::Access::kUndefined);
- Global("a", st, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a", st, ast::StorageClass::kNone, ast::AttributeList{GroupAndBinding(0, 0)});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: storage texture missing access control");
@@ -976,12 +987,12 @@
auto* st = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d,
ast::TexelFormat::kR32Uint, ast::Access::kReadWrite);
- Global("a", st, ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a", st, ast::StorageClass::kNone, nullptr,
+ ast::AttributeList{GroupAndBinding(0, 0)});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: storage textures currently only support 'write' "
- "access control");
+ "12:34 error: storage textures currently only support 'write' access control");
}
TEST_F(StorageTextureAccessTest, ReadOnlyAccess_Fail) {
@@ -991,12 +1002,12 @@
auto* st = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d,
ast::TexelFormat::kR32Uint, ast::Access::kRead);
- Global("a", st, ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a", st, ast::StorageClass::kNone, nullptr,
+ ast::AttributeList{GroupAndBinding(0, 0)});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: storage textures currently only support 'write' "
- "access control");
+ "12:34 error: storage textures currently only support 'write' access control");
}
TEST_F(StorageTextureAccessTest, WriteOnlyAccess_Pass) {
@@ -1006,7 +1017,8 @@
auto* st = ty.storage_texture(ast::TextureDimension::k1d, ast::TexelFormat::kR32Uint,
ast::Access::kWrite);
- Global("a", st, ast::StorageClass::kNone, nullptr, ast::AttributeList{GroupAndBinding(0, 0)});
+ GlobalVar("a", st, ast::StorageClass::kNone, nullptr,
+ ast::AttributeList{GroupAndBinding(0, 0)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
@@ -1029,8 +1041,11 @@
TEST_P(ValidMatrixTypes, Okay) {
// var a : matNxM<EL_TY>;
auto& params = GetParam();
- Global("a", ty.mat(params.elem_ty(*this), params.columns, params.rows),
- ast::StorageClass::kPrivate);
+
+ Enable(ast::Extension::kF16);
+
+ GlobalVar("a", ty.mat(params.elem_ty(*this), params.columns, params.rows),
+ ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
@@ -1046,16 +1061,31 @@
ParamsFor<f32>(4, 4),
ParamsFor<alias<f32>>(4, 2),
ParamsFor<alias<f32>>(4, 3),
- ParamsFor<alias<f32>>(4, 4)));
+ ParamsFor<alias<f32>>(4, 4),
+ ParamsFor<f16>(2, 2),
+ ParamsFor<f16>(2, 3),
+ ParamsFor<f16>(2, 4),
+ ParamsFor<f16>(3, 2),
+ ParamsFor<f16>(3, 3),
+ ParamsFor<f16>(3, 4),
+ ParamsFor<f16>(4, 2),
+ ParamsFor<f16>(4, 3),
+ ParamsFor<f16>(4, 4),
+ ParamsFor<alias<f16>>(4, 2),
+ ParamsFor<alias<f16>>(4, 3),
+ ParamsFor<alias<f16>>(4, 4)));
using InvalidMatrixElementTypes = ResolverTestWithParam<Params>;
TEST_P(InvalidMatrixElementTypes, InvalidElementType) {
// var a : matNxM<EL_TY>;
auto& params = GetParam();
- Global("a", ty.mat(Source{{12, 34}}, params.elem_ty(*this), params.columns, params.rows),
- ast::StorageClass::kPrivate);
+
+ Enable(ast::Extension::kF16);
+
+ GlobalVar("a", ty.mat(Source{{12, 34}}, params.elem_ty(*this), params.columns, params.rows),
+ ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: matrix element type must be 'f32'");
+ EXPECT_EQ(r()->error(), "12:34 error: matrix element type must be 'f32' or 'f16'");
}
INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
InvalidMatrixElementTypes,
@@ -1063,12 +1093,17 @@
ParamsFor<i32>(4, 3),
ParamsFor<u32>(4, 4),
ParamsFor<vec2<f32>>(2, 2),
+ ParamsFor<vec2<f16>>(2, 2),
ParamsFor<vec3<i32>>(2, 3),
ParamsFor<vec4<u32>>(2, 4),
ParamsFor<mat2x2<f32>>(3, 2),
ParamsFor<mat3x3<f32>>(3, 3),
ParamsFor<mat4x4<f32>>(3, 4),
- ParamsFor<array<2, f32>>(4, 2)));
+ ParamsFor<mat2x2<f16>>(3, 2),
+ ParamsFor<mat3x3<f16>>(3, 3),
+ ParamsFor<mat4x4<f16>>(3, 4),
+ ParamsFor<array<2, f32>>(4, 2),
+ ParamsFor<array<2, f16>>(4, 2)));
} // namespace MatrixTests
namespace VectorTests {
@@ -1086,25 +1121,32 @@
TEST_P(ValidVectorTypes, Okay) {
// var a : vecN<EL_TY>;
auto& params = GetParam();
- Global("a", ty.vec(params.elem_ty(*this), params.width), ast::StorageClass::kPrivate);
+
+ Enable(ast::Extension::kF16);
+
+ GlobalVar("a", ty.vec(params.elem_ty(*this), params.width), ast::StorageClass::kPrivate);
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
ValidVectorTypes,
testing::Values(ParamsFor<bool>(2),
ParamsFor<f32>(2),
+ ParamsFor<f16>(2),
ParamsFor<i32>(2),
ParamsFor<u32>(2),
ParamsFor<bool>(3),
ParamsFor<f32>(3),
+ ParamsFor<f16>(3),
ParamsFor<i32>(3),
ParamsFor<u32>(3),
ParamsFor<bool>(4),
ParamsFor<f32>(4),
+ ParamsFor<f16>(4),
ParamsFor<i32>(4),
ParamsFor<u32>(4),
ParamsFor<alias<bool>>(4),
ParamsFor<alias<f32>>(4),
+ ParamsFor<alias<f16>>(4),
ParamsFor<alias<i32>>(4),
ParamsFor<alias<u32>>(4)));
@@ -1112,11 +1154,14 @@
TEST_P(InvalidVectorElementTypes, InvalidElementType) {
// var a : vecN<EL_TY>;
auto& params = GetParam();
- Global("a", ty.vec(Source{{12, 34}}, params.elem_ty(*this), params.width),
- ast::StorageClass::kPrivate);
+
+ Enable(ast::Extension::kF16);
+
+ GlobalVar("a", ty.vec(Source{{12, 34}}, params.elem_ty(*this), params.width),
+ ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: vector element type must be 'bool', 'f32', 'i32' "
+ "12:34 error: vector element type must be 'bool', 'f32', 'f16', 'i32' "
"or 'u32'");
}
INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
@@ -1125,7 +1170,7 @@
ParamsFor<vec3<i32>>(2),
ParamsFor<vec4<u32>>(2),
ParamsFor<mat2x2<f32>>(2),
- ParamsFor<mat3x3<f32>>(2),
+ ParamsFor<mat3x3<f16>>(2),
ParamsFor<mat4x4<f32>>(2),
ParamsFor<array<2, f32>>(2)));
} // namespace VectorTests
diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc
index 15ca72f..57bf6b0 100644
--- a/src/tint/resolver/uniformity.cc
+++ b/src/tint/resolver/uniformity.cc
@@ -982,7 +982,7 @@
};
auto name = builder_->Symbols().NameFor(ident->symbol);
- auto* sem = sem_.Get<sem::VariableUser>(ident)->Variable();
+ auto* sem = sem_.Get(ident)->UnwrapMaterialize()->As<sem::VariableUser>()->Variable();
auto* node = CreateNode(name + "_ident_expr", ident);
return Switch(
sem,
diff --git a/src/tint/resolver/uniformity_test.cc b/src/tint/resolver/uniformity_test.cc
index 002f841..b335c27 100644
--- a/src/tint/resolver/uniformity_test.cc
+++ b/src/tint/resolver/uniformity_test.cc
@@ -84,7 +84,7 @@
kTrue,
kFalse,
kLiteral,
- kModuleLet,
+ kModuleConst,
kPipelineOverridable,
kFuncLetUniformRhs,
kFuncVarUniform,
@@ -137,8 +137,8 @@
return "false";
case kLiteral:
return "7 == 7";
- case kModuleLet:
- return "module_let == 0";
+ case kModuleConst:
+ return "module_const == 0";
case kPipelineOverridable:
return "pipeline_overridable == 0";
case kFuncLetUniformRhs:
@@ -231,7 +231,7 @@
CASE(kTrue);
CASE(kFalse);
CASE(kLiteral);
- CASE(kModuleLet);
+ CASE(kModuleConst);
CASE(kPipelineOverridable);
CASE(kFuncLetUniformRhs);
CASE(kFuncVarUniform);
@@ -290,7 +290,7 @@
@group(1) @binding(2) var s : sampler;
@group(1) @binding(3) var sc : sampler_comparison;
-let module_let : i32 = 42;
+const module_const : i32 = 42;
@id(42) override pipeline_overridable : i32;
fn user_no_restriction() {}
@@ -5327,7 +5327,7 @@
// workgroupBarrier();
// }
// }
- b.Global("non_uniform_global", ty.i32(), ast::StorageClass::kPrivate);
+ b.GlobalVar("non_uniform_global", ty.i32(), ast::StorageClass::kPrivate);
ast::StatementList main_body;
ast::ExpressionList args;
for (int i = 0; i < 255; i++) {
@@ -6538,7 +6538,7 @@
// workgroupBarrier();
// }
// }
- b.Global("v0", ty.i32(), ast::StorageClass::kPrivate, b.Expr(0_i));
+ b.GlobalVar("v0", ty.i32(), ast::StorageClass::kPrivate, b.Expr(0_i));
ast::StatementList foo_body;
std::string v_last = "v0";
for (int i = 1; i < 100000; i++) {
diff --git a/src/tint/resolver/validation_test.cc b/src/tint/resolver/validation_test.cc
index 9177d6b..20cf1ea 100644
--- a/src/tint/resolver/validation_test.cc
+++ b/src/tint/resolver/validation_test.cc
@@ -61,8 +61,8 @@
};
TEST_F(ResolverValidationTest, WorkgroupMemoryUsedInVertexStage) {
- Global(Source{{1, 2}}, "wg", ty.vec4<f32>(), ast::StorageClass::kWorkgroup);
- Global("dst", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{1, 2}}, "wg", ty.vec4<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("dst", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* stmt = Assign(Expr("dst"), Expr(Source{{3, 4}}, "wg"));
Func(Source{{9, 10}}, "f0", {}, ty.vec4<f32>(),
@@ -93,8 +93,8 @@
// f1();
//}
- Global(Source{{1, 2}}, "wg", ty.vec4<f32>(), ast::StorageClass::kWorkgroup);
- Global("dst", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar(Source{{1, 2}}, "wg", ty.vec4<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("dst", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* stmt = Assign(Expr("dst"), Expr(Source{{3, 4}}, "wg"));
Func(Source{{5, 6}}, "f2", {}, ty.void_(), {stmt});
@@ -221,7 +221,7 @@
// return;
// }
- Global("global_var", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
+ GlobalVar("global_var", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
Func("my_func", {}, ty.void_(),
{
@@ -324,11 +324,11 @@
TEST_F(ResolverValidationTest, StorageClass_SamplerExplicitStorageClass) {
auto* t = ty.sampler(ast::SamplerKind::kSampler);
- Global(Source{{12, 34}}, "var", t, ast::StorageClass::kHandle,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{12, 34}}, "var", t, ast::StorageClass::kHandle,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
EXPECT_FALSE(r()->Resolve());
@@ -338,11 +338,11 @@
TEST_F(ResolverValidationTest, StorageClass_TextureExplicitStorageClass) {
auto* t = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
- Global(Source{{12, 34}}, "var", t, ast::StorageClass::kHandle,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar(Source{{12, 34}}, "var", t, ast::StorageClass::kHandle,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
EXPECT_FALSE(r()->Resolve()) << r()->error();
@@ -351,7 +351,7 @@
}
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadChar) {
- Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_vec", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* ident = Expr(Source{{{3, 3}, {3, 7}}}, "xyqz");
@@ -363,7 +363,7 @@
}
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_MixedChars) {
- Global("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* ident = Expr(Source{{{3, 3}, {3, 7}}}, "rgyw");
@@ -376,7 +376,7 @@
}
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadLength) {
- Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_vec", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* ident = Expr(Source{{{3, 3}, {3, 8}}}, "zzzzz");
auto* mem = MemberAccessor("my_vec", ident);
@@ -387,7 +387,7 @@
}
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadIndex) {
- Global("my_vec", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_vec", ty.vec2<f32>(), ast::StorageClass::kPrivate);
auto* ident = Expr(Source{{3, 3}}, "z");
auto* mem = MemberAccessor("my_vec", ident);
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index e03aa13..a2e7799 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -307,31 +307,31 @@
return true;
}
-bool Validator::Materialize(const sem::Materialize* m) const {
- auto* from = m->Expr()->Type();
- auto* to = m->Type();
-
+bool Validator::Materialize(const sem::Type* to,
+ const sem::Type* from,
+ const Source& source) const {
if (sem::Type::ConversionRank(from, to) == sem::Type::kNoConversion) {
AddError("cannot convert value of type '" + sem_.TypeNameOf(from) + "' to type '" +
sem_.TypeNameOf(to) + "'",
- m->Expr()->Declaration()->source);
+ source);
return false;
}
return true;
}
-bool Validator::VariableConstructorOrCast(const ast::Variable* v,
- ast::StorageClass storage_class,
- const sem::Type* storage_ty,
- const sem::Type* rhs_ty) const {
- auto* value_type = rhs_ty->UnwrapRef(); // Implicit load of RHS
+bool Validator::VariableInitializer(const ast::Variable* v,
+ ast::StorageClass storage_class,
+ const sem::Type* storage_ty,
+ const sem::Expression* initializer) const {
+ auto* initializer_ty = initializer->Type();
+ auto* value_type = initializer_ty->UnwrapRef(); // Implicit load of RHS
// Value type has to match storage type
if (storage_ty != value_type) {
- std::string decl = v->Is<ast::Let>() ? "let" : "var";
- AddError("cannot initialize " + decl + " of type '" + sem_.TypeNameOf(storage_ty) +
- "' with value of type '" + sem_.TypeNameOf(rhs_ty) + "'",
- v->source);
+ std::stringstream s;
+ s << "cannot initialize " << v->Kind() << " of type '" << sem_.TypeNameOf(storage_ty)
+ << "' with value of type '" << sem_.TypeNameOf(initializer_ty) << "'";
+ AddError(s.str(), v->source);
return false;
}
@@ -529,12 +529,52 @@
std::unordered_map<uint32_t, const sem::Variable*> constant_ids,
std::unordered_map<const sem::Type*, const Source&> atomic_composite_info) const {
auto* decl = global->Declaration();
- if (!NoDuplicateAttributes(decl->attributes)) {
- return false;
- }
-
bool ok = Switch(
decl, //
+ [&](const ast::Var* var) {
+ if (global->StorageClass() == ast::StorageClass::kNone) {
+ AddError("module-scope 'var' declaration must have a storage class", decl->source);
+ return false;
+ }
+
+ for (auto* attr : decl->attributes) {
+ bool is_shader_io_attribute =
+ attr->IsAnyOf<ast::BuiltinAttribute, ast::InterpolateAttribute,
+ ast::InvariantAttribute, ast::LocationAttribute>();
+ bool has_io_storage_class = global->StorageClass() == ast::StorageClass::kInput ||
+ global->StorageClass() == ast::StorageClass::kOutput;
+ if (!attr->IsAnyOf<ast::BindingAttribute, ast::GroupAttribute,
+ ast::InternalAttribute>() &&
+ (!is_shader_io_attribute || !has_io_storage_class)) {
+ AddError("attribute is not valid for module-scope 'var'", attr->source);
+ return false;
+ }
+ }
+
+ // https://gpuweb.github.io/gpuweb/wgsl/#variable-declaration
+ // The access mode always has a default, and except for variables in the
+ // storage storage class, must not be written.
+ if (global->StorageClass() != ast::StorageClass::kStorage &&
+ var->declared_access != ast::Access::kUndefined) {
+ AddError("only variables in <storage> storage class may declare an access mode",
+ var->source);
+ return false;
+ }
+
+ if (!AtomicVariable(global, atomic_composite_info)) {
+ return false;
+ }
+
+ return Var(global);
+ },
+ [&](const ast::Let*) {
+ if (!decl->attributes.empty()) {
+ AddError("attribute is not valid for module-scope 'let' declaration",
+ decl->attributes[0]->source);
+ return false;
+ }
+ return Let(global);
+ },
[&](const ast::Override*) {
for (auto* attr : decl->attributes) {
if (auto* id_attr = attr->As<ast::IdAttribute>()) {
@@ -558,31 +598,21 @@
return false;
}
}
- return true;
+ return Override(global);
},
- [&](const ast::Let*) {
+ [&](const ast::Const*) {
if (!decl->attributes.empty()) {
- AddError("attribute is not valid for module-scope 'let' declaration",
+ AddError("attribute is not valid for module-scope 'const' declaration",
decl->attributes[0]->source);
return false;
}
- return true;
+ return Const(global);
},
- [&](const ast::Var*) {
- for (auto* attr : decl->attributes) {
- bool is_shader_io_attribute =
- attr->IsAnyOf<ast::BuiltinAttribute, ast::InterpolateAttribute,
- ast::InvariantAttribute, ast::LocationAttribute>();
- bool has_io_storage_class = global->StorageClass() == ast::StorageClass::kInput ||
- global->StorageClass() == ast::StorageClass::kOutput;
- if (!attr->IsAnyOf<ast::BindingAttribute, ast::GroupAttribute,
- ast::InternalAttribute>() &&
- (!is_shader_io_attribute || !has_io_storage_class)) {
- AddError("attribute is not valid for module-scope 'var'", attr->source);
- return false;
- }
- }
- return true;
+ [&](Default) {
+ TINT_ICE(Resolver, diagnostics_)
+ << "Validator::GlobalVariable() called with a unknown variable type: "
+ << decl->TypeInfo().name;
+ return false;
});
if (!ok) {
@@ -618,23 +648,7 @@
}
}
- if (auto* var = decl->As<ast::Var>()) {
- // https://gpuweb.github.io/gpuweb/wgsl/#variable-declaration
- // The access mode always has a default, and except for variables in the
- // storage storage class, must not be written.
- if (global->StorageClass() != ast::StorageClass::kStorage &&
- var->declared_access != ast::Access::kUndefined) {
- AddError("only variables in <storage> storage class may declare an access mode",
- var->source);
- return false;
- }
-
- if (!AtomicVariable(global, atomic_composite_info)) {
- return false;
- }
- }
-
- return Variable(global);
+ return true;
}
// https://gpuweb.github.io/gpuweb/wgsl/#atomic-types
@@ -680,65 +694,119 @@
bool Validator::Variable(const sem::Variable* v) const {
auto* decl = v->Declaration();
+ return Switch(
+ decl, //
+ [&](const ast::Var*) { return Var(v); }, //
+ [&](const ast::Let*) { return Let(v); }, //
+ [&](const ast::Override*) { return Override(v); }, //
+ [&](const ast::Const*) { return true; }, //
+ [&](Default) {
+ TINT_ICE(Resolver, diagnostics_)
+ << "Validator::Variable() called with a unknown variable type: "
+ << decl->TypeInfo().name;
+ return false;
+ });
+}
+
+bool Validator::Var(const sem::Variable* v) const {
+ auto* var = v->Declaration()->As<ast::Var>();
auto* storage_ty = v->Type()->UnwrapRef();
- auto* as_let = decl->As<ast::Let>();
- auto* as_var = decl->As<ast::Var>();
-
if (v->Is<sem::GlobalVariable>()) {
- auto name = symbols_.NameFor(decl->symbol);
+ auto name = symbols_.NameFor(var->symbol);
if (sem::ParseBuiltinType(name) != sem::BuiltinType::kNone) {
- auto* kind = as_let ? "let" : "var";
- AddError(
- "'" + name + "' is a builtin and cannot be redeclared as a module-scope " + kind,
- decl->source);
+ AddError("'" + name + "' is a builtin and cannot be redeclared as a module-scope 'var'",
+ var->source);
return false;
}
}
- if (as_var && !IsStorable(storage_ty)) {
- AddError(sem_.TypeNameOf(storage_ty) + " cannot be used as the type of a var",
- decl->source);
+ if (!IsStorable(storage_ty)) {
+ AddError(sem_.TypeNameOf(storage_ty) + " cannot be used as the type of a var", var->source);
return false;
}
- if (as_let && !(storage_ty->IsConstructible() || storage_ty->Is<sem::Pointer>())) {
- AddError(sem_.TypeNameOf(storage_ty) + " cannot be used as the type of a let",
- decl->source);
- return false;
- }
-
- if (v->Is<sem::LocalVariable>() && as_var &&
- IsValidationEnabled(decl->attributes, ast::DisabledValidation::kIgnoreStorageClass)) {
+ if (v->Is<sem::LocalVariable>() &&
+ IsValidationEnabled(var->attributes, ast::DisabledValidation::kIgnoreStorageClass)) {
if (!v->Type()->UnwrapRef()->IsConstructible()) {
- AddError("function variable must have a constructible type",
- decl->type ? decl->type->source : decl->source);
+ AddError("function-scope 'var' must have a constructible type",
+ var->type ? var->type->source : var->source);
return false;
}
}
- if (as_var && storage_ty->is_handle() &&
- as_var->declared_storage_class != ast::StorageClass::kNone) {
+ if (storage_ty->is_handle() && var->declared_storage_class != ast::StorageClass::kNone) {
// https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
// If the store type is a texture type or a sampler type, then the
// variable declaration must not have a storage class attribute. The
// storage class will always be handle.
AddError(
"variables of type '" + sem_.TypeNameOf(storage_ty) + "' must not have a storage class",
- decl->source);
+ var->source);
return false;
}
- if (IsValidationEnabled(decl->attributes, ast::DisabledValidation::kIgnoreStorageClass) &&
- as_var &&
- (as_var->declared_storage_class == ast::StorageClass::kInput ||
- as_var->declared_storage_class == ast::StorageClass::kOutput)) {
- AddError("invalid use of input/output storage class", as_var->source);
+ if (IsValidationEnabled(var->attributes, ast::DisabledValidation::kIgnoreStorageClass) &&
+ (var->declared_storage_class == ast::StorageClass::kInput ||
+ var->declared_storage_class == ast::StorageClass::kOutput)) {
+ AddError("invalid use of input/output storage class", var->source);
return false;
}
return true;
}
+bool Validator::Let(const sem::Variable* v) const {
+ auto* decl = v->Declaration();
+ auto* storage_ty = v->Type()->UnwrapRef();
+
+ if (v->Is<sem::GlobalVariable>()) {
+ auto name = symbols_.NameFor(decl->symbol);
+ if (sem::ParseBuiltinType(name) != sem::BuiltinType::kNone) {
+ AddError("'" + name + "' is a builtin and cannot be redeclared as a 'let'",
+ decl->source);
+ return false;
+ }
+ }
+
+ if (!(storage_ty->IsConstructible() || storage_ty->Is<sem::Pointer>())) {
+ AddError(sem_.TypeNameOf(storage_ty) + " cannot be used as the type of a 'let'",
+ decl->source);
+ return false;
+ }
+ return true;
+}
+
+bool Validator::Override(const sem::Variable* v) const {
+ auto* decl = v->Declaration();
+ auto* storage_ty = v->Type()->UnwrapRef();
+
+ auto name = symbols_.NameFor(decl->symbol);
+ if (sem::ParseBuiltinType(name) != sem::BuiltinType::kNone) {
+ AddError("'" + name + "' is a builtin and cannot be redeclared as a 'override'",
+ decl->source);
+ return false;
+ }
+
+ if (!storage_ty->is_scalar()) {
+ AddError(sem_.TypeNameOf(storage_ty) + " cannot be used as the type of a 'override'",
+ decl->source);
+ return false;
+ }
+ return true;
+}
+
+bool Validator::Const(const sem::Variable* v) const {
+ auto* decl = v->Declaration();
+
+ auto name = symbols_.NameFor(decl->symbol);
+ if (sem::ParseBuiltinType(name) != sem::BuiltinType::kNone) {
+ AddError("'" + name + "' is a builtin and cannot be redeclared as a 'const'", decl->source);
+ return false;
+ }
+
+ return true;
+}
+
bool Validator::Parameter(const ast::Function* func, const sem::Variable* var) const {
auto* decl = var->Declaration();
@@ -1536,16 +1604,16 @@
auto& signature = builtin->Signature();
auto check_arg_is_constexpr = [&](sem::ParameterUsage usage, int min, int max) {
- auto index = signature.IndexOf(usage);
- if (index < 0) {
+ auto signed_index = signature.IndexOf(usage);
+ if (signed_index < 0) {
return true;
}
+ auto index = static_cast<size_t>(signed_index);
std::string name = sem::str(usage);
auto* arg = call->Arguments()[index];
if (auto values = arg->ConstantValue()) {
// Assert that the constant values are of the expected type.
- if (!values.Type()->IsAnyOf<sem::I32, sem::Vector>() ||
- !values.ElementType()->Is<sem::I32>()) {
+ if (!values->Type()->is_integer_scalar_or_vector()) {
TINT_ICE(Resolver, diagnostics_)
<< "failed to resolve '" + func_name + "' " << name << " parameter type";
return false;
@@ -1563,24 +1631,26 @@
return ast::TraverseAction::Stop;
});
if (is_const_expr) {
- auto vector = builtin->Parameters()[index]->Type()->Is<sem::Vector>();
- for (size_t i = 0, n = values.ElementCount(); i < n; i++) {
- auto value = values.Element<AInt>(i).value;
- if (value < min || value > max) {
- if (vector) {
+ if (auto* vector = builtin->Parameters()[index]->Type()->As<sem::Vector>()) {
+ for (size_t i = 0; i < vector->Width(); i++) {
+ auto value = values->Index(i)->As<AInt>();
+ if (value < min || value > max) {
AddError("each component of the " + name +
" argument must be at least " + std::to_string(min) +
" and at most " + std::to_string(max) + ". " + name +
" component " + std::to_string(i) + " is " +
std::to_string(value),
arg->Declaration()->source);
- } else {
- AddError("the " + name + " argument must be at least " +
- std::to_string(min) + " and at most " +
- std::to_string(max) + ". " + name + " is " +
- std::to_string(value),
- arg->Declaration()->source);
+ return false;
}
+ }
+ } else {
+ auto value = values->As<AInt>();
+ if (value < min || value > max) {
+ AddError("the " + name + " argument must be at least " +
+ std::to_string(min) + " and at most " + std::to_string(max) +
+ ". " + name + " is " + std::to_string(value),
+ arg->Declaration()->source);
return false;
}
}
@@ -1625,6 +1695,11 @@
auto sym = decl->target.name->symbol;
auto name = symbols_.NameFor(sym);
+ if (!current_statement) { // Function call at module-scope.
+ AddError("functions cannot be called at module-scope", decl->source);
+ return false;
+ }
+
if (target->Declaration()->IsEntryPoint()) {
// https://www.w3.org/TR/WGSL/#function-restriction
// An entry point must never be the target of a function call.
@@ -1797,7 +1872,7 @@
bool Validator::Vector(const sem::Vector* ty, const Source& source) const {
if (!ty->type()->is_scalar()) {
- AddError("vector element type must be 'bool', 'f32', 'i32' or 'u32'", source);
+ AddError("vector element type must be 'bool', 'f32', 'f16', 'i32' or 'u32'", source);
return false;
}
return true;
@@ -1805,7 +1880,7 @@
bool Validator::Matrix(const sem::Matrix* ty, const Source& source) const {
if (!ty->is_float_matrix()) {
- AddError("matrix element type must be 'f32'", source);
+ AddError("matrix element type must be 'f32' or 'f16'", source);
return false;
}
return true;
diff --git a/src/tint/resolver/validator.h b/src/tint/resolver/validator.h
index 30dcaf9..4fdac53 100644
--- a/src/tint/resolver/validator.h
+++ b/src/tint/resolver/validator.h
@@ -283,10 +283,12 @@
/// @returns true on success, false otherwise.
bool LoopStatement(const sem::LoopStatement* stmt) const;
- /// Validates a materialize of an abstract numeric value
- /// @param m the materialize to validate
+ /// Validates a materialize of an abstract numeric value from the type `from` to the type `to`.
+ /// @param to the target type
+ /// @param from the abstract numeric type
+ /// @param source the source of the materialization
/// @returns true on success, false otherwise
- bool Materialize(const sem::Materialize* m) const;
+ bool Materialize(const sem::Type* to, const sem::Type* from, const Source& source) const;
/// Validates a matrix
/// @param ty the matrix to validate
@@ -352,20 +354,40 @@
bool SwitchStatement(const ast::SwitchStatement* s);
/// Validates a variable
- /// @param var the variable to validate
+ /// @param v the variable to validate
/// @returns true on success, false otherwise.
- bool Variable(const sem::Variable* var) const;
+ bool Variable(const sem::Variable* v) const;
- /// Validates a variable constructor or cast
+ /// Validates a 'var' variable declaration
+ /// @param v the variable to validate
+ /// @returns true on success, false otherwise.
+ bool Var(const sem::Variable* v) const;
+
+ /// Validates a 'let' variable declaration
+ /// @param v the variable to validate
+ /// @returns true on success, false otherwise.
+ bool Let(const sem::Variable* v) const;
+
+ /// Validates a 'override' variable declaration
+ /// @param v the variable to validate
+ /// @returns true on success, false otherwise.
+ bool Override(const sem::Variable* v) const;
+
+ /// Validates a 'const' variable declaration
+ /// @param v the variable to validate
+ /// @returns true on success, false otherwise.
+ bool Const(const sem::Variable* v) const;
+
+ /// Validates a variable initializer
/// @param v the variable to validate
/// @param storage_class the storage class of the variable
/// @param storage_type the type of the storage
- /// @param rhs_type the right hand side of the expression
+ /// @param initializer the RHS initializer expression
/// @returns true on succes, false otherwise
- bool VariableConstructorOrCast(const ast::Variable* v,
- ast::StorageClass storage_class,
- const sem::Type* storage_type,
- const sem::Type* rhs_type) const;
+ bool VariableInitializer(const ast::Variable* v,
+ ast::StorageClass storage_class,
+ const sem::Type* storage_type,
+ const sem::Expression* initializer) const;
/// Validates a vector
/// @param ty the vector to validate
diff --git a/src/tint/resolver/validator_is_storeable_test.cc b/src/tint/resolver/validator_is_storeable_test.cc
index a5f612c..88ec911 100644
--- a/src/tint/resolver/validator_is_storeable_test.cc
+++ b/src/tint/resolver/validator_is_storeable_test.cc
@@ -32,6 +32,7 @@
EXPECT_TRUE(v()->IsStorable(create<sem::I32>()));
EXPECT_TRUE(v()->IsStorable(create<sem::U32>()));
EXPECT_TRUE(v()->IsStorable(create<sem::F32>()));
+ EXPECT_TRUE(v()->IsStorable(create<sem::F16>()));
}
TEST_F(ValidatorIsStorableTest, Vector) {
@@ -44,21 +45,36 @@
EXPECT_TRUE(v()->IsStorable(create<sem::Vector>(create<sem::F32>(), 2u)));
EXPECT_TRUE(v()->IsStorable(create<sem::Vector>(create<sem::F32>(), 3u)));
EXPECT_TRUE(v()->IsStorable(create<sem::Vector>(create<sem::F32>(), 4u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Vector>(create<sem::F16>(), 2u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Vector>(create<sem::F16>(), 3u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Vector>(create<sem::F16>(), 4u)));
}
TEST_F(ValidatorIsStorableTest, Matrix) {
- auto* vec2 = create<sem::Vector>(create<sem::F32>(), 2u);
- auto* vec3 = create<sem::Vector>(create<sem::F32>(), 3u);
- auto* vec4 = create<sem::Vector>(create<sem::F32>(), 4u);
- EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec2, 2u)));
- EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec2, 3u)));
- EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec2, 4u)));
- EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec3, 2u)));
- EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec3, 3u)));
- EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec3, 4u)));
- EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec4, 2u)));
- EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec4, 3u)));
- EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec4, 4u)));
+ auto* vec2_f32 = create<sem::Vector>(create<sem::F32>(), 2u);
+ auto* vec3_f32 = create<sem::Vector>(create<sem::F32>(), 3u);
+ auto* vec4_f32 = create<sem::Vector>(create<sem::F32>(), 4u);
+ auto* vec2_f16 = create<sem::Vector>(create<sem::F16>(), 2u);
+ auto* vec3_f16 = create<sem::Vector>(create<sem::F16>(), 3u);
+ auto* vec4_f16 = create<sem::Vector>(create<sem::F16>(), 4u);
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec2_f32, 2u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec2_f32, 3u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec2_f32, 4u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec3_f32, 2u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec3_f32, 3u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec3_f32, 4u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec4_f32, 2u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec4_f32, 3u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec4_f32, 4u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec2_f16, 2u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec2_f16, 3u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec2_f16, 4u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec3_f16, 2u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec3_f16, 3u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec3_f16, 4u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec4_f16, 2u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec4_f16, 3u)));
+ EXPECT_TRUE(v()->IsStorable(create<sem::Matrix>(vec4_f16, 4u)));
}
TEST_F(ValidatorIsStorableTest, Pointer) {
diff --git a/src/tint/resolver/var_let_test.cc b/src/tint/resolver/var_let_test.cc
deleted file mode 100644
index 4306736..0000000
--- a/src/tint/resolver/var_let_test.cc
+++ /dev/null
@@ -1,676 +0,0 @@
-// Copyright 2021 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/resolver/resolver.h"
-#include "src/tint/resolver/resolver_test_helper.h"
-#include "src/tint/sem/reference.h"
-
-#include "gmock/gmock.h"
-
-using namespace tint::number_suffixes; // NOLINT
-
-namespace tint::resolver {
-namespace {
-
-struct ResolverVarLetTest : public resolver::TestHelper, public testing::Test {};
-
-TEST_F(ResolverVarLetTest, VarDeclWithoutConstructor) {
- // struct S { i : i32; }
- // alias A = S;
- // fn F(){
- // var i : i32;
- // var u : u32;
- // var f : f32;
- // var b : bool;
- // var s : S;
- // var a : A;
- // }
-
- auto* S = Structure("S", {Member("i", ty.i32())});
- auto* A = Alias("A", ty.Of(S));
-
- auto* i = Var("i", ty.i32(), ast::StorageClass::kNone);
- auto* u = Var("u", ty.u32(), ast::StorageClass::kNone);
- auto* f = Var("f", ty.f32(), ast::StorageClass::kNone);
- auto* b = Var("b", ty.bool_(), ast::StorageClass::kNone);
- auto* s = Var("s", ty.Of(S), ast::StorageClass::kNone);
- auto* a = Var("a", ty.Of(A), ast::StorageClass::kNone);
-
- Func("F", {}, ty.void_(),
- {
- Decl(i),
- Decl(u),
- Decl(f),
- Decl(b),
- Decl(s),
- Decl(a),
- });
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- // `var` declarations are always of reference type
- ASSERT_TRUE(TypeOf(i)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(u)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(f)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(b)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(s)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(a)->Is<sem::Reference>());
-
- EXPECT_TRUE(TypeOf(i)->As<sem::Reference>()->StoreType()->Is<sem::I32>());
- EXPECT_TRUE(TypeOf(u)->As<sem::Reference>()->StoreType()->Is<sem::U32>());
- EXPECT_TRUE(TypeOf(f)->As<sem::Reference>()->StoreType()->Is<sem::F32>());
- EXPECT_TRUE(TypeOf(b)->As<sem::Reference>()->StoreType()->Is<sem::Bool>());
- EXPECT_TRUE(TypeOf(s)->As<sem::Reference>()->StoreType()->Is<sem::Struct>());
- EXPECT_TRUE(TypeOf(a)->As<sem::Reference>()->StoreType()->Is<sem::Struct>());
-
- EXPECT_EQ(Sem().Get(i)->Constructor(), nullptr);
- EXPECT_EQ(Sem().Get(u)->Constructor(), nullptr);
- EXPECT_EQ(Sem().Get(f)->Constructor(), nullptr);
- EXPECT_EQ(Sem().Get(b)->Constructor(), nullptr);
- EXPECT_EQ(Sem().Get(s)->Constructor(), nullptr);
- EXPECT_EQ(Sem().Get(a)->Constructor(), nullptr);
-}
-
-TEST_F(ResolverVarLetTest, VarDeclWithConstructor) {
- // struct S { i : i32; }
- // alias A = S;
- // fn F(){
- // var i : i32 = 1i;
- // var u : u32 = 1u;
- // var f : f32 = 1.f;
- // var b : bool = true;
- // var s : S = S(1);
- // var a : A = A(1);
- // }
-
- auto* S = Structure("S", {Member("i", ty.i32())});
- auto* A = Alias("A", ty.Of(S));
-
- auto* i_c = Expr(1_i);
- auto* u_c = Expr(1_u);
- auto* f_c = Expr(1_f);
- auto* b_c = Expr(true);
- auto* s_c = Construct(ty.Of(S), Expr(1_i));
- auto* a_c = Construct(ty.Of(A), Expr(1_i));
-
- auto* i = Var("i", ty.i32(), ast::StorageClass::kNone, i_c);
- auto* u = Var("u", ty.u32(), ast::StorageClass::kNone, u_c);
- auto* f = Var("f", ty.f32(), ast::StorageClass::kNone, f_c);
- auto* b = Var("b", ty.bool_(), ast::StorageClass::kNone, b_c);
- auto* s = Var("s", ty.Of(S), ast::StorageClass::kNone, s_c);
- auto* a = Var("a", ty.Of(A), ast::StorageClass::kNone, a_c);
-
- Func("F", {}, ty.void_(),
- {
- Decl(i),
- Decl(u),
- Decl(f),
- Decl(b),
- Decl(s),
- Decl(a),
- });
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- // `var` declarations are always of reference type
- ASSERT_TRUE(TypeOf(i)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(u)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(f)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(b)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(s)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(a)->Is<sem::Reference>());
-
- EXPECT_TRUE(TypeOf(i)->As<sem::Reference>()->StoreType()->Is<sem::I32>());
- EXPECT_TRUE(TypeOf(u)->As<sem::Reference>()->StoreType()->Is<sem::U32>());
- EXPECT_TRUE(TypeOf(f)->As<sem::Reference>()->StoreType()->Is<sem::F32>());
- EXPECT_TRUE(TypeOf(b)->As<sem::Reference>()->StoreType()->Is<sem::Bool>());
- EXPECT_TRUE(TypeOf(s)->As<sem::Reference>()->StoreType()->Is<sem::Struct>());
- EXPECT_TRUE(TypeOf(a)->As<sem::Reference>()->StoreType()->Is<sem::Struct>());
-
- EXPECT_EQ(Sem().Get(i)->Constructor()->Declaration(), i_c);
- EXPECT_EQ(Sem().Get(u)->Constructor()->Declaration(), u_c);
- EXPECT_EQ(Sem().Get(f)->Constructor()->Declaration(), f_c);
- EXPECT_EQ(Sem().Get(b)->Constructor()->Declaration(), b_c);
- EXPECT_EQ(Sem().Get(s)->Constructor()->Declaration(), s_c);
- EXPECT_EQ(Sem().Get(a)->Constructor()->Declaration(), a_c);
-}
-
-TEST_F(ResolverVarLetTest, LetDecl) {
- // struct S { i : i32; }
- // fn F(){
- // var v : i32;
- // let i : i32 = 1i;
- // let u : u32 = 1u;
- // let f : f32 = 1.;
- // let b : bool = true;
- // let s : S = S(1);
- // let a : A = A(1);
- // let p : pointer<function, i32> = &v;
- // }
-
- auto* S = Structure("S", {Member("i", ty.i32())});
- auto* A = Alias("A", ty.Of(S));
- auto* v = Var("v", ty.i32(), ast::StorageClass::kNone);
-
- auto* i_c = Expr(1_i);
- auto* u_c = Expr(1_u);
- auto* f_c = Expr(1_f);
- auto* b_c = Expr(true);
- auto* s_c = Construct(ty.Of(S), Expr(1_i));
- auto* a_c = Construct(ty.Of(A), Expr(1_i));
- auto* p_c = AddressOf(v);
-
- auto* i = Let("i", ty.i32(), i_c);
- auto* u = Let("u", ty.u32(), u_c);
- auto* f = Let("f", ty.f32(), f_c);
- auto* b = Let("b", ty.bool_(), b_c);
- auto* s = Let("s", ty.Of(S), s_c);
- auto* a = Let("a", ty.Of(A), a_c);
- auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), p_c);
-
- Func("F", {}, ty.void_(),
- {
- Decl(v),
- Decl(i),
- Decl(u),
- Decl(f),
- Decl(b),
- Decl(s),
- Decl(a),
- Decl(p),
- });
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- // `let` declarations are always of the storage type
- ASSERT_TRUE(TypeOf(i)->Is<sem::I32>());
- ASSERT_TRUE(TypeOf(u)->Is<sem::U32>());
- ASSERT_TRUE(TypeOf(f)->Is<sem::F32>());
- ASSERT_TRUE(TypeOf(b)->Is<sem::Bool>());
- ASSERT_TRUE(TypeOf(s)->Is<sem::Struct>());
- ASSERT_TRUE(TypeOf(a)->Is<sem::Struct>());
- ASSERT_TRUE(TypeOf(p)->Is<sem::Pointer>());
- ASSERT_TRUE(TypeOf(p)->As<sem::Pointer>()->StoreType()->Is<sem::I32>());
-
- EXPECT_EQ(Sem().Get(i)->Constructor()->Declaration(), i_c);
- EXPECT_EQ(Sem().Get(u)->Constructor()->Declaration(), u_c);
- EXPECT_EQ(Sem().Get(f)->Constructor()->Declaration(), f_c);
- EXPECT_EQ(Sem().Get(b)->Constructor()->Declaration(), b_c);
- EXPECT_EQ(Sem().Get(s)->Constructor()->Declaration(), s_c);
- EXPECT_EQ(Sem().Get(a)->Constructor()->Declaration(), a_c);
- EXPECT_EQ(Sem().Get(p)->Constructor()->Declaration(), p_c);
-}
-
-TEST_F(ResolverVarLetTest, DefaultVarStorageClass) {
- // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
-
- auto* buf = Structure("S", {Member("m", ty.i32())});
- auto* function = Var("f", ty.i32());
- auto* private_ = Global("p", ty.i32(), ast::StorageClass::kPrivate);
- auto* workgroup = Global("w", ty.i32(), ast::StorageClass::kWorkgroup);
- auto* uniform = Global("ub", ty.Of(buf), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
- auto* storage = Global("sb", ty.Of(buf), ast::StorageClass::kStorage,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(0),
- });
- auto* handle = Global("h", ty.depth_texture(ast::TextureDimension::k2d),
- ast::AttributeList{
- create<ast::BindingAttribute>(2),
- create<ast::GroupAttribute>(0),
- });
-
- WrapInFunction(function);
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- ASSERT_TRUE(TypeOf(function)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(private_)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(workgroup)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(uniform)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(storage)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(handle)->Is<sem::Reference>());
-
- EXPECT_EQ(TypeOf(function)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
- EXPECT_EQ(TypeOf(private_)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
- EXPECT_EQ(TypeOf(workgroup)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
- EXPECT_EQ(TypeOf(uniform)->As<sem::Reference>()->Access(), ast::Access::kRead);
- EXPECT_EQ(TypeOf(storage)->As<sem::Reference>()->Access(), ast::Access::kRead);
- EXPECT_EQ(TypeOf(handle)->As<sem::Reference>()->Access(), ast::Access::kRead);
-}
-
-TEST_F(ResolverVarLetTest, ExplicitVarStorageClass) {
- // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
-
- auto* buf = Structure("S", {Member("m", ty.i32())});
- auto* storage = Global("sb", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(0),
- });
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- ASSERT_TRUE(TypeOf(storage)->Is<sem::Reference>());
-
- EXPECT_EQ(TypeOf(storage)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
-}
-
-TEST_F(ResolverVarLetTest, LetInheritsAccessFromOriginatingVariable) {
- // struct Inner {
- // arr: array<i32, 4>;
- // }
- // struct S {
- // inner: Inner;
- // }
- // @group(0) @binding(0) var<storage, read_write> s : S;
- // fn f() {
- // let p = &s.inner.arr[4];
- // }
- auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
- auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
- auto* storage = Global("s", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
-
- auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 4_i);
- auto* ptr = Let("p", nullptr, AddressOf(expr));
-
- WrapInFunction(ptr);
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- ASSERT_TRUE(TypeOf(expr)->Is<sem::Reference>());
- ASSERT_TRUE(TypeOf(ptr)->Is<sem::Pointer>());
-
- EXPECT_EQ(TypeOf(expr)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
- EXPECT_EQ(TypeOf(ptr)->As<sem::Pointer>()->Access(), ast::Access::kReadWrite);
-}
-
-TEST_F(ResolverVarLetTest, LocalShadowsAlias) {
- // type a = i32;
- //
- // fn X() {
- // var a = false;
- // }
- //
- // fn Y() {
- // let a = true;
- // }
-
- auto* t = Alias("a", ty.i32());
- auto* v = Var("a", nullptr, Expr(false));
- auto* l = Let("a", nullptr, Expr(false));
- Func("X", {}, ty.void_(), {Decl(v)});
- Func("Y", {}, ty.void_(), {Decl(l)});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* type_t = Sem().Get(t);
- auto* local_v = Sem().Get<sem::LocalVariable>(v);
- auto* local_l = Sem().Get<sem::LocalVariable>(l);
-
- ASSERT_NE(local_v, nullptr);
- ASSERT_NE(local_l, nullptr);
-
- EXPECT_EQ(local_v->Shadows(), type_t);
- EXPECT_EQ(local_l->Shadows(), type_t);
-}
-
-TEST_F(ResolverVarLetTest, LocalShadowsStruct) {
- // struct a {
- // m : i32;
- // };
- //
- // fn X() {
- // var a = true;
- // }
- //
- // fn Y() {
- // let a = false;
- // }
-
- auto* t = Structure("a", {Member("m", ty.i32())});
- auto* v = Var("a", nullptr, Expr(false));
- auto* l = Let("a", nullptr, Expr(false));
- Func("X", {}, ty.void_(), {Decl(v)});
- Func("Y", {}, ty.void_(), {Decl(l)});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* type_t = Sem().Get(t);
- auto* local_v = Sem().Get<sem::LocalVariable>(v);
- auto* local_l = Sem().Get<sem::LocalVariable>(l);
-
- ASSERT_NE(local_v, nullptr);
- ASSERT_NE(local_l, nullptr);
-
- EXPECT_EQ(local_v->Shadows(), type_t);
- EXPECT_EQ(local_l->Shadows(), type_t);
-}
-
-TEST_F(ResolverVarLetTest, LocalShadowsFunction) {
- // fn a() {
- // var a = true;
- // }
- //
- // fn b() {
- // let b = false;
- // }
-
- auto* v = Var("a", nullptr, Expr(false));
- auto* l = Let("b", nullptr, Expr(false));
- auto* fa = Func("a", {}, ty.void_(), {Decl(v)});
- auto* fb = Func("b", {}, ty.void_(), {Decl(l)});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* local_v = Sem().Get<sem::LocalVariable>(v);
- auto* local_l = Sem().Get<sem::LocalVariable>(l);
- auto* func_a = Sem().Get(fa);
- auto* func_b = Sem().Get(fb);
-
- ASSERT_NE(local_v, nullptr);
- ASSERT_NE(local_l, nullptr);
- ASSERT_NE(func_a, nullptr);
- ASSERT_NE(func_b, nullptr);
-
- EXPECT_EQ(local_v->Shadows(), func_a);
- EXPECT_EQ(local_l->Shadows(), func_b);
-}
-
-TEST_F(ResolverVarLetTest, LocalShadowsGlobalVar) {
- // var<private> a : i32;
- //
- // fn X() {
- // var a = a;
- // }
- //
- // fn Y() {
- // let a = a;
- // }
-
- auto* g = Global("a", ty.i32(), ast::StorageClass::kPrivate);
- auto* v = Var("a", nullptr, Expr("a"));
- auto* l = Let("a", nullptr, Expr("a"));
- Func("X", {}, ty.void_(), {Decl(v)});
- Func("Y", {}, ty.void_(), {Decl(l)});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* global = Sem().Get(g);
- auto* local_v = Sem().Get<sem::LocalVariable>(v);
- auto* local_l = Sem().Get<sem::LocalVariable>(l);
-
- ASSERT_NE(local_v, nullptr);
- ASSERT_NE(local_l, nullptr);
-
- EXPECT_EQ(local_v->Shadows(), global);
- EXPECT_EQ(local_l->Shadows(), global);
-
- auto* user_v = Sem().Get<sem::VariableUser>(local_v->Declaration()->constructor);
- auto* user_l = Sem().Get<sem::VariableUser>(local_l->Declaration()->constructor);
-
- ASSERT_NE(user_v, nullptr);
- ASSERT_NE(user_l, nullptr);
-
- EXPECT_EQ(user_v->Variable(), global);
- EXPECT_EQ(user_l->Variable(), global);
-}
-
-TEST_F(ResolverVarLetTest, LocalShadowsGlobalLet) {
- // let a : i32 = 1;
- //
- // fn X() {
- // var a = (a == 123);
- // }
- //
- // fn Y() {
- // let a = (a == 321);
- // }
-
- auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
- auto* v = Var("a", nullptr, Expr("a"));
- auto* l = Let("a", nullptr, Expr("a"));
- Func("X", {}, ty.void_(), {Decl(v)});
- Func("Y", {}, ty.void_(), {Decl(l)});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* global = Sem().Get(g);
- auto* local_v = Sem().Get<sem::LocalVariable>(v);
- auto* local_l = Sem().Get<sem::LocalVariable>(l);
-
- ASSERT_NE(local_v, nullptr);
- ASSERT_NE(local_l, nullptr);
-
- EXPECT_EQ(local_v->Shadows(), global);
- EXPECT_EQ(local_l->Shadows(), global);
-
- auto* user_v = Sem().Get<sem::VariableUser>(local_v->Declaration()->constructor);
- auto* user_l = Sem().Get<sem::VariableUser>(local_l->Declaration()->constructor);
-
- ASSERT_NE(user_v, nullptr);
- ASSERT_NE(user_l, nullptr);
-
- EXPECT_EQ(user_v->Variable(), global);
- EXPECT_EQ(user_l->Variable(), global);
-}
-
-TEST_F(ResolverVarLetTest, LocalShadowsLocalVar) {
- // fn X() {
- // var a : i32;
- // {
- // var a = a;
- // }
- // {
- // let a = a;
- // }
- // }
-
- auto* s = Var("a", ty.i32(), Expr(1_i));
- auto* v = Var("a", nullptr, Expr("a"));
- auto* l = Let("a", nullptr, Expr("a"));
- Func("X", {}, ty.void_(), {Decl(s), Block(Decl(v)), Block(Decl(l))});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* local_s = Sem().Get<sem::LocalVariable>(s);
- auto* local_v = Sem().Get<sem::LocalVariable>(v);
- auto* local_l = Sem().Get<sem::LocalVariable>(l);
-
- ASSERT_NE(local_s, nullptr);
- ASSERT_NE(local_v, nullptr);
- ASSERT_NE(local_l, nullptr);
-
- EXPECT_EQ(local_v->Shadows(), local_s);
- EXPECT_EQ(local_l->Shadows(), local_s);
-
- auto* user_v = Sem().Get<sem::VariableUser>(local_v->Declaration()->constructor);
- auto* user_l = Sem().Get<sem::VariableUser>(local_l->Declaration()->constructor);
-
- ASSERT_NE(user_v, nullptr);
- ASSERT_NE(user_l, nullptr);
-
- EXPECT_EQ(user_v->Variable(), local_s);
- EXPECT_EQ(user_l->Variable(), local_s);
-}
-
-TEST_F(ResolverVarLetTest, LocalShadowsLocalLet) {
- // fn X() {
- // let a = 1;
- // {
- // var a = (a == 123);
- // }
- // {
- // let a = (a == 321);
- // }
- // }
-
- auto* s = Let("a", ty.i32(), Expr(1_i));
- auto* v = Var("a", nullptr, Expr("a"));
- auto* l = Let("a", nullptr, Expr("a"));
- Func("X", {}, ty.void_(), {Decl(s), Block(Decl(v)), Block(Decl(l))});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* local_s = Sem().Get<sem::LocalVariable>(s);
- auto* local_v = Sem().Get<sem::LocalVariable>(v);
- auto* local_l = Sem().Get<sem::LocalVariable>(l);
-
- ASSERT_NE(local_s, nullptr);
- ASSERT_NE(local_v, nullptr);
- ASSERT_NE(local_l, nullptr);
-
- EXPECT_EQ(local_v->Shadows(), local_s);
- EXPECT_EQ(local_l->Shadows(), local_s);
-
- auto* user_v = Sem().Get<sem::VariableUser>(local_v->Declaration()->constructor);
- auto* user_l = Sem().Get<sem::VariableUser>(local_l->Declaration()->constructor);
-
- ASSERT_NE(user_v, nullptr);
- ASSERT_NE(user_l, nullptr);
-
- EXPECT_EQ(user_v->Variable(), local_s);
- EXPECT_EQ(user_l->Variable(), local_s);
-}
-
-TEST_F(ResolverVarLetTest, LocalShadowsParam) {
- // fn F(a : i32) {
- // {
- // var a = a;
- // }
- // {
- // let a = a;
- // }
- // }
-
- auto* p = Param("a", ty.i32());
- auto* v = Var("a", nullptr, Expr("a"));
- auto* l = Let("a", nullptr, Expr("a"));
- Func("X", {p}, ty.void_(), {Block(Decl(v)), Block(Decl(l))});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* param = Sem().Get<sem::Parameter>(p);
- auto* local_v = Sem().Get<sem::LocalVariable>(v);
- auto* local_l = Sem().Get<sem::LocalVariable>(l);
-
- ASSERT_NE(param, nullptr);
- ASSERT_NE(local_v, nullptr);
- ASSERT_NE(local_l, nullptr);
-
- EXPECT_EQ(local_v->Shadows(), param);
- EXPECT_EQ(local_l->Shadows(), param);
-
- auto* user_v = Sem().Get<sem::VariableUser>(local_v->Declaration()->constructor);
- auto* user_l = Sem().Get<sem::VariableUser>(local_l->Declaration()->constructor);
-
- ASSERT_NE(user_v, nullptr);
- ASSERT_NE(user_l, nullptr);
-
- EXPECT_EQ(user_v->Variable(), param);
- EXPECT_EQ(user_l->Variable(), param);
-}
-
-TEST_F(ResolverVarLetTest, ParamShadowsFunction) {
- // fn a(a : bool) {
- // }
-
- auto* p = Param("a", ty.bool_());
- auto* f = Func("a", {p}, ty.void_(), {});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* func = Sem().Get(f);
- auto* param = Sem().Get<sem::Parameter>(p);
-
- ASSERT_NE(func, nullptr);
- ASSERT_NE(param, nullptr);
-
- EXPECT_EQ(param->Shadows(), func);
-}
-
-TEST_F(ResolverVarLetTest, ParamShadowsGlobalVar) {
- // var<private> a : i32;
- //
- // fn F(a : bool) {
- // }
-
- auto* g = Global("a", ty.i32(), ast::StorageClass::kPrivate);
- auto* p = Param("a", ty.bool_());
- Func("F", {p}, ty.void_(), {});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* global = Sem().Get(g);
- auto* param = Sem().Get<sem::Parameter>(p);
-
- ASSERT_NE(global, nullptr);
- ASSERT_NE(param, nullptr);
-
- EXPECT_EQ(param->Shadows(), global);
-}
-
-TEST_F(ResolverVarLetTest, ParamShadowsGlobalLet) {
- // let a : i32 = 1;
- //
- // fn F(a : bool) {
- // }
-
- auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
- auto* p = Param("a", ty.bool_());
- Func("F", {p}, ty.void_(), {});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* global = Sem().Get(g);
- auto* param = Sem().Get<sem::Parameter>(p);
-
- ASSERT_NE(global, nullptr);
- ASSERT_NE(param, nullptr);
-
- EXPECT_EQ(param->Shadows(), global);
-}
-
-TEST_F(ResolverVarLetTest, ParamShadowsAlias) {
- // type a = i32;
- //
- // fn F(a : a) {
- // }
-
- auto* a = Alias("a", ty.i32());
- auto* p = Param("a", ty.type_name("a"));
- Func("F", {p}, ty.void_(), {});
-
- ASSERT_TRUE(r()->Resolve()) << r()->error();
-
- auto* alias = Sem().Get(a);
- auto* param = Sem().Get<sem::Parameter>(p);
-
- ASSERT_NE(alias, nullptr);
- ASSERT_NE(param, nullptr);
-
- EXPECT_EQ(param->Shadows(), alias);
- EXPECT_EQ(param->Type(), alias);
-}
-
-} // namespace
-} // namespace tint::resolver
diff --git a/src/tint/resolver/var_let_validation_test.cc b/src/tint/resolver/var_let_validation_test.cc
deleted file mode 100644
index 67ecd53..0000000
--- a/src/tint/resolver/var_let_validation_test.cc
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright 2021 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/resolver/resolver.h"
-#include "src/tint/resolver/resolver_test_helper.h"
-
-#include "gmock/gmock.h"
-
-using namespace tint::number_suffixes; // NOLINT
-
-namespace tint::resolver {
-namespace {
-
-struct ResolverVarLetValidationTest : public resolver::TestHelper, public testing::Test {};
-
-TEST_F(ResolverVarLetValidationTest, VarNoInitializerNoType) {
- // var a;
- WrapInFunction(Var(Source{{12, 34}}, "a", nullptr));
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: function-scope 'var' declaration requires a type or initializer");
-}
-
-TEST_F(ResolverVarLetValidationTest, GlobalVarNoInitializerNoType) {
- // var a;
- Global(Source{{12, 34}}, "a", nullptr);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: module-scope 'var' declaration requires a type or initializer");
-}
-
-TEST_F(ResolverVarLetValidationTest, VarTypeNotStorable) {
- // var i : i32;
- // var p : pointer<function, i32> = &v;
- auto* i = Var("i", ty.i32(), ast::StorageClass::kNone);
- auto* p = Var(Source{{56, 78}}, "a", ty.pointer<i32>(ast::StorageClass::kFunction),
- ast::StorageClass::kNone, AddressOf(Source{{12, 34}}, "i"));
- WrapInFunction(i, p);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "56:78 error: ptr<function, i32, read_write> cannot be used as the "
- "type of a var");
-}
-
-TEST_F(ResolverVarLetValidationTest, LetTypeNotConstructible) {
- // @group(0) @binding(0) var t1 : texture_2d<f32>;
- // let t2 : t1;
- auto* t1 = Global("t1", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
- GroupAndBinding(0, 0));
- auto* t2 = Let(Source{{56, 78}}, "t2", nullptr, Expr(t1));
- WrapInFunction(t2);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "56:78 error: texture_2d<f32> cannot be used as the type of a let");
-}
-
-TEST_F(ResolverVarLetValidationTest, LetConstructorWrongType) {
- // var v : i32 = 2u
- WrapInFunction(Let(Source{{3, 3}}, "v", ty.i32(), Expr(2_u)));
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- R"(3:3 error: cannot initialize let of type 'i32' with value of type 'u32')");
-}
-
-TEST_F(ResolverVarLetValidationTest, VarConstructorWrongType) {
- // var v : i32 = 2u
- WrapInFunction(Var(Source{{3, 3}}, "v", ty.i32(), ast::StorageClass::kNone, Expr(2_u)));
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- R"(3:3 error: cannot initialize var of type 'i32' with value of type 'u32')");
-}
-
-TEST_F(ResolverVarLetValidationTest, LetConstructorWrongTypeViaAlias) {
- auto* a = Alias("I32", ty.i32());
- WrapInFunction(Let(Source{{3, 3}}, "v", ty.Of(a), Expr(2_u)));
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- R"(3:3 error: cannot initialize let of type 'i32' with value of type 'u32')");
-}
-
-TEST_F(ResolverVarLetValidationTest, VarConstructorWrongTypeViaAlias) {
- auto* a = Alias("I32", ty.i32());
- WrapInFunction(Var(Source{{3, 3}}, "v", ty.Of(a), ast::StorageClass::kNone, Expr(2_u)));
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- R"(3:3 error: cannot initialize var of type 'i32' with value of type 'u32')");
-}
-
-TEST_F(ResolverVarLetValidationTest, LetOfPtrConstructedWithRef) {
- // var a : f32;
- // let b : ptr<function,f32> = a;
- const auto priv = ast::StorageClass::kFunction;
- auto* var_a = Var("a", ty.f32(), priv);
- auto* var_b = Let(Source{{12, 34}}, "b", ty.pointer<f32>(priv), Expr("a"), {});
- WrapInFunction(var_a, var_b);
-
- ASSERT_FALSE(r()->Resolve());
-
- EXPECT_EQ(
- r()->error(),
- R"(12:34 error: cannot initialize let of type 'ptr<function, f32, read_write>' with value of type 'f32')");
-}
-
-TEST_F(ResolverVarLetValidationTest, LocalLetRedeclared) {
- // let l : f32 = 1.;
- // let l : i32 = 0;
- auto* l1 = Let("l", ty.f32(), Expr(1_f));
- auto* l2 = Let(Source{{12, 34}}, "l", ty.i32(), Expr(0_i));
- WrapInFunction(l1, l2);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: redeclaration of 'l'\nnote: 'l' previously declared here");
-}
-
-TEST_F(ResolverVarLetValidationTest, GlobalVarRedeclaredAsLocal) {
- // var v : f32 = 2.1;
- // fn my_func() {
- // var v : f32 = 2.0;
- // return 0;
- // }
-
- Global("v", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
-
- WrapInFunction(Var(Source{{12, 34}}, "v", ty.f32(), ast::StorageClass::kNone, Expr(2_f)));
-
- EXPECT_TRUE(r()->Resolve()) << r()->error();
-}
-
-TEST_F(ResolverVarLetValidationTest, VarRedeclaredInInnerBlock) {
- // {
- // var v : f32;
- // { var v : f32; }
- // }
- auto* var_outer = Var("v", ty.f32(), ast::StorageClass::kNone);
- auto* var_inner = Var(Source{{12, 34}}, "v", ty.f32(), ast::StorageClass::kNone);
- auto* inner = Block(Decl(var_inner));
- auto* outer_body = Block(Decl(var_outer), inner);
-
- WrapInFunction(outer_body);
-
- EXPECT_TRUE(r()->Resolve()) << r()->error();
-}
-
-TEST_F(ResolverVarLetValidationTest, VarRedeclaredInIfBlock) {
- // {
- // var v : f32 = 3.14;
- // if (true) { var v : f32 = 2.0; }
- // }
- auto* var_a_float = Var("v", ty.f32(), ast::StorageClass::kNone, Expr(3.1_f));
-
- auto* var = Var(Source{{12, 34}}, "v", ty.f32(), ast::StorageClass::kNone, Expr(2_f));
-
- auto* cond = Expr(true);
- auto* body = Block(Decl(var));
-
- auto* outer_body = Block(Decl(var_a_float), If(cond, body));
-
- WrapInFunction(outer_body);
-
- EXPECT_TRUE(r()->Resolve()) << r()->error();
-}
-
-TEST_F(ResolverVarLetValidationTest, InferredPtrStorageAccessMismatch) {
- // struct Inner {
- // arr: array<i32, 4>;
- // }
- // struct S {
- // inner: Inner;
- // }
- // @group(0) @binding(0) var<storage> s : S;
- // fn f() {
- // let p : pointer<storage, i32, read_write> = &s.inner.arr[2i];
- // }
- auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
- auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
- auto* storage = Global("s", ty.Of(buf), ast::StorageClass::kStorage,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
-
- auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 2_i);
- auto* ptr =
- Let(Source{{12, 34}}, "p",
- ty.pointer<i32>(ast::StorageClass::kStorage, ast::Access::kReadWrite), AddressOf(expr));
-
- WrapInFunction(ptr);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: cannot initialize let of type "
- "'ptr<storage, i32, read_write>' with value of type "
- "'ptr<storage, i32, read>'");
-}
-
-TEST_F(ResolverVarLetValidationTest, NonConstructibleType_Atomic) {
- auto* v = Var("v", ty.atomic(Source{{12, 34}}, ty.i32()));
- WrapInFunction(v);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: function variable must have a constructible type");
-}
-
-TEST_F(ResolverVarLetValidationTest, NonConstructibleType_RuntimeArray) {
- auto* s = Structure("S", {Member(Source{{56, 78}}, "m", ty.array(ty.i32()))});
- auto* v = Var(Source{{12, 34}}, "v", ty.Of(s));
- WrapInFunction(v);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
-56:78 note: while analysing structure member S.m
-12:34 note: while instantiating variable v)");
-}
-
-TEST_F(ResolverVarLetValidationTest, NonConstructibleType_Struct_WithAtomic) {
- auto* s = Structure("S", {Member("m", ty.atomic(ty.i32()))});
- auto* v = Var("v", ty.Of(s));
- WrapInFunction(v);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "error: function variable must have a constructible type");
-}
-
-TEST_F(ResolverVarLetValidationTest, NonConstructibleType_InferredType) {
- // @group(0) @binding(0) var s : sampler;
- // fn foo() {
- // var v = s;
- // }
- Global("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(0, 0));
- auto* v = Var(Source{{12, 34}}, "v", nullptr, Expr("s"));
- WrapInFunction(v);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: function variable must have a constructible type");
-}
-
-TEST_F(ResolverVarLetValidationTest, InvalidStorageClassForInitializer) {
- // var<workgroup> v : f32 = 1.23;
- Global(Source{{12, 34}}, "v", ty.f32(), ast::StorageClass::kWorkgroup, Expr(1.23_f));
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: var of storage class 'workgroup' cannot have "
- "an initializer. var initializers are only supported for the "
- "storage classes 'private' and 'function'");
-}
-
-TEST_F(ResolverVarLetValidationTest, VectorLetNoType) {
- // let a : mat3x3 = mat3x3<f32>();
- WrapInFunction(Let("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3), vec3<f32>()));
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
-}
-
-TEST_F(ResolverVarLetValidationTest, VectorVarNoType) {
- // var a : mat3x3;
- WrapInFunction(Var("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3)));
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
-}
-
-TEST_F(ResolverVarLetValidationTest, MatrixLetNoType) {
- // let a : mat3x3 = mat3x3<f32>();
- WrapInFunction(Let("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3, 3), mat3x3<f32>()));
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
-}
-
-TEST_F(ResolverVarLetValidationTest, MatrixVarNoType) {
- // var a : mat3x3;
- WrapInFunction(Var("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3, 3)));
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
-}
-
-} // namespace
-} // namespace tint::resolver
diff --git a/src/tint/resolver/variable_test.cc b/src/tint/resolver/variable_test.cc
new file mode 100644
index 0000000..7eb0dea
--- /dev/null
+++ b/src/tint/resolver/variable_test.cc
@@ -0,0 +1,1288 @@
+// Copyright 2021 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/resolver/resolver.h"
+#include "src/tint/resolver/resolver_test_helper.h"
+#include "src/tint/sem/reference.h"
+
+#include "gmock/gmock.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::resolver {
+namespace {
+
+struct ResolverVariableTest : public resolver::TestHelper, public testing::Test {};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Function-scope 'var'
+////////////////////////////////////////////////////////////////////////////////////////////////////
+TEST_F(ResolverVariableTest, LocalVar_NoConstructor) {
+ // struct S { i : i32; }
+ // alias A = S;
+ // fn F(){
+ // var i : i32;
+ // var u : u32;
+ // var f : f32;
+ // var h : f16;
+ // var b : bool;
+ // var s : S;
+ // var a : A;
+ // }
+
+ Enable(ast::Extension::kF16);
+
+ auto* S = Structure("S", {Member("i", ty.i32())});
+ auto* A = Alias("A", ty.Of(S));
+
+ auto* i = Var("i", ty.i32(), ast::StorageClass::kNone);
+ auto* u = Var("u", ty.u32(), ast::StorageClass::kNone);
+ auto* f = Var("f", ty.f32(), ast::StorageClass::kNone);
+ auto* h = Var("h", ty.f16(), ast::StorageClass::kNone);
+ auto* b = Var("b", ty.bool_(), ast::StorageClass::kNone);
+ auto* s = Var("s", ty.Of(S), ast::StorageClass::kNone);
+ auto* a = Var("a", ty.Of(A), ast::StorageClass::kNone);
+
+ Func("F", {}, ty.void_(),
+ {
+ Decl(i),
+ Decl(u),
+ Decl(f),
+ Decl(h),
+ Decl(b),
+ Decl(s),
+ Decl(a),
+ });
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ // `var` declarations are always of reference type
+ ASSERT_TRUE(TypeOf(i)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(u)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(f)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(h)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(b)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(s)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(a)->Is<sem::Reference>());
+
+ EXPECT_TRUE(TypeOf(i)->As<sem::Reference>()->StoreType()->Is<sem::I32>());
+ EXPECT_TRUE(TypeOf(u)->As<sem::Reference>()->StoreType()->Is<sem::U32>());
+ EXPECT_TRUE(TypeOf(f)->As<sem::Reference>()->StoreType()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(h)->As<sem::Reference>()->StoreType()->Is<sem::F16>());
+ EXPECT_TRUE(TypeOf(b)->As<sem::Reference>()->StoreType()->Is<sem::Bool>());
+ EXPECT_TRUE(TypeOf(s)->As<sem::Reference>()->StoreType()->Is<sem::Struct>());
+ EXPECT_TRUE(TypeOf(a)->As<sem::Reference>()->StoreType()->Is<sem::Struct>());
+
+ EXPECT_EQ(Sem().Get(i)->Constructor(), nullptr);
+ EXPECT_EQ(Sem().Get(u)->Constructor(), nullptr);
+ EXPECT_EQ(Sem().Get(f)->Constructor(), nullptr);
+ EXPECT_EQ(Sem().Get(h)->Constructor(), nullptr);
+ EXPECT_EQ(Sem().Get(b)->Constructor(), nullptr);
+ EXPECT_EQ(Sem().Get(s)->Constructor(), nullptr);
+ EXPECT_EQ(Sem().Get(a)->Constructor(), nullptr);
+}
+
+TEST_F(ResolverVariableTest, LocalVar_WithConstructor) {
+ // struct S { i : i32; }
+ // alias A = S;
+ // fn F(){
+ // var i : i32 = 1i;
+ // var u : u32 = 1u;
+ // var f : f32 = 1.f;
+ // var h : f16 = 1.h;
+ // var b : bool = true;
+ // var s : S = S(1);
+ // var a : A = A(1);
+ // }
+
+ Enable(ast::Extension::kF16);
+
+ auto* S = Structure("S", {Member("i", ty.i32())});
+ auto* A = Alias("A", ty.Of(S));
+
+ auto* i_c = Expr(1_i);
+ auto* u_c = Expr(1_u);
+ auto* f_c = Expr(1_f);
+ auto* h_c = Expr(1_h);
+ auto* b_c = Expr(true);
+ auto* s_c = Construct(ty.Of(S), Expr(1_i));
+ auto* a_c = Construct(ty.Of(A), Expr(1_i));
+
+ auto* i = Var("i", ty.i32(), ast::StorageClass::kNone, i_c);
+ auto* u = Var("u", ty.u32(), ast::StorageClass::kNone, u_c);
+ auto* f = Var("f", ty.f32(), ast::StorageClass::kNone, f_c);
+ auto* h = Var("h", ty.f16(), ast::StorageClass::kNone, h_c);
+ auto* b = Var("b", ty.bool_(), ast::StorageClass::kNone, b_c);
+ auto* s = Var("s", ty.Of(S), ast::StorageClass::kNone, s_c);
+ auto* a = Var("a", ty.Of(A), ast::StorageClass::kNone, a_c);
+
+ Func("F", {}, ty.void_(),
+ {
+ Decl(i),
+ Decl(u),
+ Decl(f),
+ Decl(h),
+ Decl(b),
+ Decl(s),
+ Decl(a),
+ });
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ // `var` declarations are always of reference type
+ ASSERT_TRUE(TypeOf(i)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(u)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(f)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(h)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(b)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(s)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(a)->Is<sem::Reference>());
+
+ EXPECT_EQ(TypeOf(i)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
+ EXPECT_EQ(TypeOf(u)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
+ EXPECT_EQ(TypeOf(f)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
+ EXPECT_EQ(TypeOf(b)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
+ EXPECT_EQ(TypeOf(s)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
+ EXPECT_EQ(TypeOf(a)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
+
+ EXPECT_TRUE(TypeOf(i)->As<sem::Reference>()->StoreType()->Is<sem::I32>());
+ EXPECT_TRUE(TypeOf(u)->As<sem::Reference>()->StoreType()->Is<sem::U32>());
+ EXPECT_TRUE(TypeOf(f)->As<sem::Reference>()->StoreType()->Is<sem::F32>());
+ EXPECT_TRUE(TypeOf(h)->As<sem::Reference>()->StoreType()->Is<sem::F16>());
+ EXPECT_TRUE(TypeOf(b)->As<sem::Reference>()->StoreType()->Is<sem::Bool>());
+ EXPECT_TRUE(TypeOf(s)->As<sem::Reference>()->StoreType()->Is<sem::Struct>());
+ EXPECT_TRUE(TypeOf(a)->As<sem::Reference>()->StoreType()->Is<sem::Struct>());
+
+ EXPECT_EQ(Sem().Get(i)->Constructor()->Declaration(), i_c);
+ EXPECT_EQ(Sem().Get(u)->Constructor()->Declaration(), u_c);
+ EXPECT_EQ(Sem().Get(f)->Constructor()->Declaration(), f_c);
+ EXPECT_EQ(Sem().Get(h)->Constructor()->Declaration(), h_c);
+ EXPECT_EQ(Sem().Get(b)->Constructor()->Declaration(), b_c);
+ EXPECT_EQ(Sem().Get(s)->Constructor()->Declaration(), s_c);
+ EXPECT_EQ(Sem().Get(a)->Constructor()->Declaration(), a_c);
+}
+
+TEST_F(ResolverVariableTest, LocalVar_ShadowsAlias) {
+ // type a = i32;
+ //
+ // fn F() {
+ // var a = false;
+ // }
+
+ auto* t = Alias("a", ty.i32());
+ auto* v = Var("a", nullptr, Expr(false));
+ Func("F", {}, ty.void_(), {Decl(v)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* type_t = Sem().Get(t);
+ auto* local = Sem().Get<sem::LocalVariable>(v);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), type_t);
+}
+
+TEST_F(ResolverVariableTest, LocalVar_ShadowsStruct) {
+ // struct a {
+ // m : i32;
+ // };
+ //
+ // fn F() {
+ // var a = true;
+ // }
+
+ auto* t = Structure("a", {Member("m", ty.i32())});
+ auto* v = Var("a", nullptr, Expr(false));
+ Func("F", {}, ty.void_(), {Decl(v)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* type_t = Sem().Get(t);
+ auto* local = Sem().Get<sem::LocalVariable>(v);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), type_t);
+}
+
+TEST_F(ResolverVariableTest, LocalVar_ShadowsFunction) {
+ // fn a() {
+ // var a = true;
+ // }
+
+ auto* v = Var("a", nullptr, Expr(false));
+ auto* f = Func("a", {}, ty.void_(), {Decl(v)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* func = Sem().Get(f);
+ ASSERT_NE(func, nullptr);
+
+ auto* local = Sem().Get<sem::LocalVariable>(v);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), func);
+}
+
+TEST_F(ResolverVariableTest, LocalVar_ShadowsGlobalVar) {
+ // var<private> a : i32;
+ //
+ // fn F() {
+ // var a = a;
+ // }
+
+ auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+ auto* v = Var("a", nullptr, Expr("a"));
+ Func("F", {}, ty.void_(), {Decl(v)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* global = Sem().Get(g);
+ auto* local = Sem().Get<sem::LocalVariable>(v);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), global);
+
+ auto* user_v = Sem().Get<sem::VariableUser>(local->Declaration()->constructor);
+ ASSERT_NE(user_v, nullptr);
+ EXPECT_EQ(user_v->Variable(), global);
+}
+
+TEST_F(ResolverVariableTest, LocalVar_ShadowsGlobalConst) {
+ // const a : i32 = 1i;
+ //
+ // fn X() {
+ // var a = (a == 123);
+ // }
+
+ auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
+ auto* v = Var("a", nullptr, Expr("a"));
+ Func("F", {}, ty.void_(), {Decl(v)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* global = Sem().Get(g);
+ auto* local = Sem().Get<sem::LocalVariable>(v);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), global);
+
+ auto* user_v = Sem().Get<sem::VariableUser>(local->Declaration()->constructor);
+ ASSERT_NE(user_v, nullptr);
+ EXPECT_EQ(user_v->Variable(), global);
+}
+
+TEST_F(ResolverVariableTest, LocalVar_ShadowsLocalVar) {
+ // fn F() {
+ // var a : i32 = 1i; // x
+ // {
+ // var a = a; // y
+ // }
+ // }
+
+ auto* x = Var("a", ty.i32(), Expr(1_i));
+ auto* y = Var("a", nullptr, Expr("a"));
+ Func("F", {}, ty.void_(), {Decl(x), Block(Decl(y))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* local_x = Sem().Get<sem::LocalVariable>(x);
+ auto* local_y = Sem().Get<sem::LocalVariable>(y);
+
+ ASSERT_NE(local_x, nullptr);
+ ASSERT_NE(local_y, nullptr);
+ EXPECT_EQ(local_y->Shadows(), local_x);
+
+ auto* user_y = Sem().Get<sem::VariableUser>(local_y->Declaration()->constructor);
+ ASSERT_NE(user_y, nullptr);
+ EXPECT_EQ(user_y->Variable(), local_x);
+}
+
+TEST_F(ResolverVariableTest, LocalVar_ShadowsLocalConst) {
+ // fn F() {
+ // const a : i32 = 1i;
+ // {
+ // var a = (a == 123);
+ // }
+ // }
+
+ auto* c = Const("a", ty.i32(), Expr(1_i));
+ auto* v = Var("a", nullptr, Expr("a"));
+ Func("X", {}, ty.void_(), {Decl(c), Block(Decl(v))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* local_c = Sem().Get<sem::LocalVariable>(c);
+ auto* local_v = Sem().Get<sem::LocalVariable>(v);
+
+ ASSERT_NE(local_c, nullptr);
+ ASSERT_NE(local_v, nullptr);
+ EXPECT_EQ(local_v->Shadows(), local_c);
+
+ auto* user_v = Sem().Get<sem::VariableUser>(local_v->Declaration()->constructor);
+ ASSERT_NE(user_v, nullptr);
+ EXPECT_EQ(user_v->Variable(), local_c);
+}
+
+TEST_F(ResolverVariableTest, LocalVar_ShadowsLocalLet) {
+ // fn F() {
+ // let a : i32 = 1i;
+ // {
+ // var a = (a == 123);
+ // }
+ // }
+
+ auto* l = Let("a", ty.i32(), Expr(1_i));
+ auto* v = Var("a", nullptr, Expr("a"));
+ Func("X", {}, ty.void_(), {Decl(l), Block(Decl(v))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* local_l = Sem().Get<sem::LocalVariable>(l);
+ auto* local_v = Sem().Get<sem::LocalVariable>(v);
+
+ ASSERT_NE(local_l, nullptr);
+ ASSERT_NE(local_v, nullptr);
+ EXPECT_EQ(local_v->Shadows(), local_l);
+
+ auto* user_v = Sem().Get<sem::VariableUser>(local_v->Declaration()->constructor);
+ ASSERT_NE(user_v, nullptr);
+ EXPECT_EQ(user_v->Variable(), local_l);
+}
+
+TEST_F(ResolverVariableTest, LocalVar_ShadowsParam) {
+ // fn F(a : i32) {
+ // {
+ // var a = a;
+ // }
+ // }
+
+ auto* p = Param("a", ty.i32());
+ auto* v = Var("a", nullptr, Expr("a"));
+ Func("X", {p}, ty.void_(), {Block(Decl(v))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* param = Sem().Get<sem::Parameter>(p);
+ auto* local = Sem().Get<sem::LocalVariable>(v);
+
+ ASSERT_NE(param, nullptr);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), param);
+
+ auto* user_v = Sem().Get<sem::VariableUser>(local->Declaration()->constructor);
+ ASSERT_NE(user_v, nullptr);
+ EXPECT_EQ(user_v->Variable(), param);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Function-scope 'let'
+////////////////////////////////////////////////////////////////////////////////////////////////////
+TEST_F(ResolverVariableTest, LocalLet) {
+ // struct S { i : i32; }
+ // fn F(){
+ // var v : i32;
+ // let i : i32 = 1i;
+ // let u : u32 = 1u;
+ // let f : f32 = 1.f;
+ // let h : h32 = 1.h;
+ // let b : bool = true;
+ // let s : S = S(1);
+ // let a : A = A(1);
+ // let p : pointer<function, i32> = &v;
+ // }
+
+ Enable(ast::Extension::kF16);
+
+ auto* S = Structure("S", {Member("i", ty.i32())});
+ auto* A = Alias("A", ty.Of(S));
+ auto* v = Var("v", ty.i32(), ast::StorageClass::kNone);
+
+ auto* i_c = Expr(1_i);
+ auto* u_c = Expr(1_u);
+ auto* f_c = Expr(1_f);
+ auto* h_c = Expr(1_h);
+ auto* b_c = Expr(true);
+ auto* s_c = Construct(ty.Of(S), Expr(1_i));
+ auto* a_c = Construct(ty.Of(A), Expr(1_i));
+ auto* p_c = AddressOf(v);
+
+ auto* i = Let("i", ty.i32(), i_c);
+ auto* u = Let("u", ty.u32(), u_c);
+ auto* f = Let("f", ty.f32(), f_c);
+ auto* h = Let("h", ty.f16(), h_c);
+ auto* b = Let("b", ty.bool_(), b_c);
+ auto* s = Let("s", ty.Of(S), s_c);
+ auto* a = Let("a", ty.Of(A), a_c);
+ auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), p_c);
+
+ Func("F", {}, ty.void_(),
+ {
+ Decl(v),
+ Decl(i),
+ Decl(u),
+ Decl(f),
+ Decl(h),
+ Decl(b),
+ Decl(s),
+ Decl(a),
+ Decl(p),
+ });
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ // `let` declarations are always of the storage type
+ ASSERT_TRUE(TypeOf(i)->Is<sem::I32>());
+ ASSERT_TRUE(TypeOf(u)->Is<sem::U32>());
+ ASSERT_TRUE(TypeOf(f)->Is<sem::F32>());
+ ASSERT_TRUE(TypeOf(h)->Is<sem::F16>());
+ ASSERT_TRUE(TypeOf(b)->Is<sem::Bool>());
+ ASSERT_TRUE(TypeOf(s)->Is<sem::Struct>());
+ ASSERT_TRUE(TypeOf(a)->Is<sem::Struct>());
+ ASSERT_TRUE(TypeOf(p)->Is<sem::Pointer>());
+ ASSERT_TRUE(TypeOf(p)->As<sem::Pointer>()->StoreType()->Is<sem::I32>());
+
+ EXPECT_EQ(Sem().Get(i)->Constructor()->Declaration(), i_c);
+ EXPECT_EQ(Sem().Get(u)->Constructor()->Declaration(), u_c);
+ EXPECT_EQ(Sem().Get(f)->Constructor()->Declaration(), f_c);
+ EXPECT_EQ(Sem().Get(h)->Constructor()->Declaration(), h_c);
+ EXPECT_EQ(Sem().Get(b)->Constructor()->Declaration(), b_c);
+ EXPECT_EQ(Sem().Get(s)->Constructor()->Declaration(), s_c);
+ EXPECT_EQ(Sem().Get(a)->Constructor()->Declaration(), a_c);
+ EXPECT_EQ(Sem().Get(p)->Constructor()->Declaration(), p_c);
+}
+
+TEST_F(ResolverVariableTest, LocalLet_InheritsAccessFromOriginatingVariable) {
+ // struct Inner {
+ // arr: array<i32, 4>;
+ // }
+ // struct S {
+ // inner: Inner;
+ // }
+ // @group(0) @binding(0) var<storage, read_write> s : S;
+ // fn f() {
+ // let p = &s.inner.arr[4];
+ // }
+ auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
+ auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
+ auto* storage = GlobalVar("s", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
+
+ auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 4_i);
+ auto* ptr = Let("p", nullptr, AddressOf(expr));
+
+ WrapInFunction(ptr);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_TRUE(TypeOf(expr)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(ptr)->Is<sem::Pointer>());
+
+ EXPECT_EQ(TypeOf(expr)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
+ EXPECT_EQ(TypeOf(ptr)->As<sem::Pointer>()->Access(), ast::Access::kReadWrite);
+}
+
+TEST_F(ResolverVariableTest, LocalLet_ShadowsAlias) {
+ // type a = i32;
+ //
+ // fn F() {
+ // let a = true;
+ // }
+
+ auto* t = Alias("a", ty.i32());
+ auto* l = Let("a", nullptr, Expr(false));
+ Func("F", {}, ty.void_(), {Decl(l)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* type_t = Sem().Get(t);
+ auto* local = Sem().Get<sem::LocalVariable>(l);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), type_t);
+}
+
+TEST_F(ResolverVariableTest, LocalLet_ShadowsStruct) {
+ // struct a {
+ // m : i32;
+ // };
+ //
+ // fn F() {
+ // let a = false;
+ // }
+
+ auto* t = Structure("a", {Member("m", ty.i32())});
+ auto* l = Let("a", nullptr, Expr(false));
+ Func("F", {}, ty.void_(), {Decl(l)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* type_t = Sem().Get(t);
+ auto* local = Sem().Get<sem::LocalVariable>(l);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), type_t);
+}
+
+TEST_F(ResolverVariableTest, LocalLet_ShadowsFunction) {
+ // fn a() {
+ // let a = false;
+ // }
+
+ auto* l = Let("a", nullptr, Expr(false));
+ auto* fb = Func("a", {}, ty.void_(), {Decl(l)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* func = Sem().Get(fb);
+ ASSERT_NE(func, nullptr);
+
+ auto* local = Sem().Get<sem::LocalVariable>(l);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), func);
+}
+
+TEST_F(ResolverVariableTest, LocalLet_ShadowsGlobalVar) {
+ // var<private> a : i32;
+ //
+ // fn F() {
+ // let a = a;
+ // }
+
+ auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+ auto* l = Let("a", nullptr, Expr("a"));
+ Func("F", {}, ty.void_(), {Decl(l)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* global = Sem().Get(g);
+ auto* local = Sem().Get<sem::LocalVariable>(l);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), global);
+
+ auto* user = Sem().Get<sem::VariableUser>(local->Declaration()->constructor);
+ ASSERT_NE(user, nullptr);
+ EXPECT_EQ(user->Variable(), global);
+}
+
+TEST_F(ResolverVariableTest, LocalLet_ShadowsGlobalConst) {
+ // const a : i32 = 1i;
+ //
+ // fn F() {
+ // let a = a;
+ // }
+
+ auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
+ auto* l = Let("a", nullptr, Expr("a"));
+ Func("F", {}, ty.void_(), {Decl(l)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* global = Sem().Get(g);
+ auto* local = Sem().Get<sem::LocalVariable>(l);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), global);
+
+ auto* user = Sem().Get<sem::VariableUser>(local->Declaration()->constructor);
+ ASSERT_NE(user, nullptr);
+ EXPECT_EQ(user->Variable(), global);
+}
+
+TEST_F(ResolverVariableTest, LocalLet_ShadowsLocalVar) {
+ // fn F() {
+ // var a : i32 = 1i;
+ // {
+ // let a = a;
+ // }
+ // }
+
+ auto* v = Var("a", ty.i32(), Expr(1_i));
+ auto* l = Let("a", nullptr, Expr("a"));
+ Func("F", {}, ty.void_(), {Decl(v), Block(Decl(l))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* local_v = Sem().Get<sem::LocalVariable>(v);
+ auto* local_l = Sem().Get<sem::LocalVariable>(l);
+
+ ASSERT_NE(local_v, nullptr);
+ ASSERT_NE(local_l, nullptr);
+ EXPECT_EQ(local_l->Shadows(), local_v);
+
+ auto* user = Sem().Get<sem::VariableUser>(local_l->Declaration()->constructor);
+ ASSERT_NE(user, nullptr);
+ EXPECT_EQ(user->Variable(), local_v);
+}
+
+TEST_F(ResolverVariableTest, LocalLet_ShadowsLocalConst) {
+ // fn X() {
+ // const a : i32 = 1i; // x
+ // {
+ // let a = a; // y
+ // }
+ // }
+
+ auto* x = Const("a", ty.i32(), Expr(1_i));
+ auto* y = Let("a", nullptr, Expr("a"));
+ Func("X", {}, ty.void_(), {Decl(x), Block(Decl(y))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* local_x = Sem().Get<sem::LocalVariable>(x);
+ auto* local_y = Sem().Get<sem::LocalVariable>(y);
+
+ ASSERT_NE(local_x, nullptr);
+ ASSERT_NE(local_y, nullptr);
+ EXPECT_EQ(local_y->Shadows(), local_x);
+
+ auto* user = Sem().Get<sem::VariableUser>(local_y->Declaration()->constructor);
+ ASSERT_NE(user, nullptr);
+ EXPECT_EQ(user->Variable(), local_x);
+}
+
+TEST_F(ResolverVariableTest, LocalLet_ShadowsLocalLet) {
+ // fn X() {
+ // let a : i32 = 1i; // x
+ // {
+ // let a = a; // y
+ // }
+ // }
+
+ auto* x = Let("a", ty.i32(), Expr(1_i));
+ auto* y = Let("a", nullptr, Expr("a"));
+ Func("X", {}, ty.void_(), {Decl(x), Block(Decl(y))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* local_x = Sem().Get<sem::LocalVariable>(x);
+ auto* local_y = Sem().Get<sem::LocalVariable>(y);
+
+ ASSERT_NE(local_x, nullptr);
+ ASSERT_NE(local_y, nullptr);
+ EXPECT_EQ(local_y->Shadows(), local_x);
+
+ auto* user = Sem().Get<sem::VariableUser>(local_y->Declaration()->constructor);
+ ASSERT_NE(user, nullptr);
+ EXPECT_EQ(user->Variable(), local_x);
+}
+
+TEST_F(ResolverVariableTest, LocalLet_ShadowsParam) {
+ // fn F(a : i32) {
+ // {
+ // let a = a;
+ // }
+ // }
+
+ auto* p = Param("a", ty.i32());
+ auto* l = Let("a", nullptr, Expr("a"));
+ Func("X", {p}, ty.void_(), {Block(Decl(l))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* param = Sem().Get<sem::Parameter>(p);
+ auto* local = Sem().Get<sem::LocalVariable>(l);
+
+ ASSERT_NE(param, nullptr);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), param);
+
+ auto* user = Sem().Get<sem::VariableUser>(local->Declaration()->constructor);
+ ASSERT_NE(user, nullptr);
+ EXPECT_EQ(user->Variable(), param);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Function-scope const
+////////////////////////////////////////////////////////////////////////////////////////////////////
+TEST_F(ResolverVariableTest, LocalConst_ShadowsAlias) {
+ // type a = i32;
+ //
+ // fn F() {
+ // const a = true;
+ // }
+
+ auto* t = Alias("a", ty.i32());
+ auto* c = Const("a", nullptr, Expr(false));
+ Func("F", {}, ty.void_(), {Decl(c)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* type_t = Sem().Get(t);
+ auto* local = Sem().Get<sem::LocalVariable>(c);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), type_t);
+}
+
+TEST_F(ResolverVariableTest, LocalConst_ShadowsStruct) {
+ // struct a {
+ // m : i32;
+ // };
+ //
+ // fn F() {
+ // const a = false;
+ // }
+
+ auto* t = Structure("a", {Member("m", ty.i32())});
+ auto* c = Const("a", nullptr, Expr(false));
+ Func("F", {}, ty.void_(), {Decl(c)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* type_t = Sem().Get(t);
+ auto* local = Sem().Get<sem::LocalVariable>(c);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), type_t);
+}
+
+TEST_F(ResolverVariableTest, LocalConst_ShadowsFunction) {
+ // fn a() {
+ // const a = false;
+ // }
+
+ auto* c = Const("a", nullptr, Expr(false));
+ auto* fb = Func("a", {}, ty.void_(), {Decl(c)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* func = Sem().Get(fb);
+ ASSERT_NE(func, nullptr);
+
+ auto* local = Sem().Get<sem::LocalVariable>(c);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), func);
+}
+
+TEST_F(ResolverVariableTest, LocalConst_ShadowsGlobalVar) {
+ // var<private> a : i32;
+ //
+ // fn F() {
+ // const a = 1i;
+ // }
+
+ auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+ auto* c = Const("a", nullptr, Expr(1_i));
+ Func("F", {}, ty.void_(), {Decl(c)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* global = Sem().Get(g);
+ auto* local = Sem().Get<sem::LocalVariable>(c);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), global);
+}
+
+TEST_F(ResolverVariableTest, LocalConst_ShadowsGlobalConst) {
+ // const a : i32 = 1i;
+ //
+ // fn F() {
+ // const a = a;
+ // }
+
+ auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
+ auto* c = Const("a", nullptr, Expr("a"));
+ Func("F", {}, ty.void_(), {Decl(c)});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* global = Sem().Get(g);
+ auto* local = Sem().Get<sem::LocalVariable>(c);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), global);
+
+ auto* user = Sem().Get<sem::VariableUser>(local->Declaration()->constructor);
+ ASSERT_NE(user, nullptr);
+ EXPECT_EQ(user->Variable(), global);
+}
+
+TEST_F(ResolverVariableTest, LocalConst_ShadowsLocalVar) {
+ // fn F() {
+ // var a = 1i;
+ // {
+ // const a = 1i;
+ // }
+ // }
+
+ auto* v = Var("a", ty.i32(), Expr(1_i));
+ auto* c = Const("a", nullptr, Expr(1_i));
+ Func("F", {}, ty.void_(), {Decl(v), Block(Decl(c))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* local_v = Sem().Get<sem::LocalVariable>(v);
+ auto* local_c = Sem().Get<sem::LocalVariable>(c);
+
+ ASSERT_NE(local_v, nullptr);
+ ASSERT_NE(local_c, nullptr);
+ EXPECT_EQ(local_c->Shadows(), local_v);
+}
+
+TEST_F(ResolverVariableTest, LocalConst_ShadowsLocalConst) {
+ // fn X() {
+ // const a = 1i; // x
+ // {
+ // const a = a; // y
+ // }
+ // }
+
+ auto* x = Const("a", ty.i32(), Expr(1_i));
+ auto* y = Const("a", nullptr, Expr("a"));
+ Func("X", {}, ty.void_(), {Decl(x), Block(Decl(y))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* local_x = Sem().Get<sem::LocalVariable>(x);
+ auto* local_y = Sem().Get<sem::LocalVariable>(y);
+
+ ASSERT_NE(local_x, nullptr);
+ ASSERT_NE(local_y, nullptr);
+ EXPECT_EQ(local_y->Shadows(), local_x);
+
+ auto* user = Sem().Get<sem::VariableUser>(local_y->Declaration()->constructor);
+ ASSERT_NE(user, nullptr);
+ EXPECT_EQ(user->Variable(), local_x);
+}
+
+TEST_F(ResolverVariableTest, LocalConst_ShadowsLocalLet) {
+ // fn X() {
+ // let a = 1i; // x
+ // {
+ // const a = 1i; // y
+ // }
+ // }
+
+ auto* l = Let("a", ty.i32(), Expr(1_i));
+ auto* c = Const("a", nullptr, Expr(1_i));
+ Func("X", {}, ty.void_(), {Decl(l), Block(Decl(c))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* local_l = Sem().Get<sem::LocalVariable>(l);
+ auto* local_c = Sem().Get<sem::LocalVariable>(c);
+
+ ASSERT_NE(local_l, nullptr);
+ ASSERT_NE(local_c, nullptr);
+ EXPECT_EQ(local_c->Shadows(), local_l);
+}
+
+TEST_F(ResolverVariableTest, LocalConst_ShadowsParam) {
+ // fn F(a : i32) {
+ // {
+ // const a = 1i;
+ // }
+ // }
+
+ auto* p = Param("a", ty.i32());
+ auto* c = Const("a", nullptr, Expr(1_i));
+ Func("X", {p}, ty.void_(), {Block(Decl(c))});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* param = Sem().Get<sem::Parameter>(p);
+ auto* local = Sem().Get<sem::LocalVariable>(c);
+
+ ASSERT_NE(param, nullptr);
+ ASSERT_NE(local, nullptr);
+ EXPECT_EQ(local->Shadows(), param);
+}
+
+TEST_F(ResolverVariableTest, LocalConst_ExplicitType_Decls) {
+ auto* c_i32 = Const("a", ty.i32(), Expr(0_i));
+ auto* c_u32 = Const("b", ty.u32(), Expr(0_u));
+ auto* c_f32 = Const("c", ty.f32(), Expr(0_f));
+ auto* c_vi32 = Const("d", ty.vec3<i32>(), vec3<i32>());
+ auto* c_vu32 = Const("e", ty.vec3<u32>(), vec3<u32>());
+ auto* c_vf32 = Const("f", ty.vec3<f32>(), vec3<f32>());
+ auto* c_mf32 = Const("g", ty.mat3x3<f32>(), mat3x3<f32>());
+
+ WrapInFunction(c_i32, c_u32, c_f32, c_vi32, c_vu32, c_vf32, c_mf32);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ EXPECT_EQ(Sem().Get(c_i32)->Declaration(), c_i32);
+ EXPECT_EQ(Sem().Get(c_u32)->Declaration(), c_u32);
+ EXPECT_EQ(Sem().Get(c_f32)->Declaration(), c_f32);
+ EXPECT_EQ(Sem().Get(c_vi32)->Declaration(), c_vi32);
+ EXPECT_EQ(Sem().Get(c_vu32)->Declaration(), c_vu32);
+ EXPECT_EQ(Sem().Get(c_vf32)->Declaration(), c_vf32);
+ EXPECT_EQ(Sem().Get(c_mf32)->Declaration(), c_mf32);
+
+ ASSERT_TRUE(TypeOf(c_i32)->Is<sem::I32>());
+ ASSERT_TRUE(TypeOf(c_u32)->Is<sem::U32>());
+ ASSERT_TRUE(TypeOf(c_f32)->Is<sem::F32>());
+ ASSERT_TRUE(TypeOf(c_vi32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vu32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vf32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_mf32)->Is<sem::Matrix>());
+
+ EXPECT_TRUE(Sem().Get(c_i32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_u32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_f32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vi32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vu32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vf32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_mf32)->ConstantValue()->AllZero());
+}
+
+TEST_F(ResolverVariableTest, LocalConst_ImplicitType_Decls) {
+ auto* c_i32 = Const("a", nullptr, Expr(0_i));
+ auto* c_u32 = Const("b", nullptr, Expr(0_u));
+ auto* c_f32 = Const("c", nullptr, Expr(0_f));
+ auto* c_ai = Const("d", nullptr, Expr(0_a));
+ auto* c_af = Const("e", nullptr, Expr(0._a));
+ auto* c_vi32 = Const("f", nullptr, vec3<i32>());
+ auto* c_vu32 = Const("g", nullptr, vec3<u32>());
+ auto* c_vf32 = Const("h", nullptr, vec3<f32>());
+ auto* c_vai = Const("i", nullptr, Construct(ty.vec(nullptr, 3), Expr(0_a)));
+ auto* c_vaf = Const("j", nullptr, Construct(ty.vec(nullptr, 3), Expr(0._a)));
+ auto* c_mf32 = Const("k", nullptr, mat3x3<f32>());
+ auto* c_maf32 = Const("l", nullptr,
+ Construct(ty.mat(nullptr, 3, 3), //
+ Construct(ty.vec(nullptr, 3), Expr(0._a)),
+ Construct(ty.vec(nullptr, 3), Expr(0._a)),
+ Construct(ty.vec(nullptr, 3), Expr(0._a))));
+
+ WrapInFunction(c_i32, c_u32, c_f32, c_ai, c_af, c_vi32, c_vu32, c_vf32, c_vai, c_vaf, c_mf32,
+ c_maf32);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ EXPECT_EQ(Sem().Get(c_i32)->Declaration(), c_i32);
+ EXPECT_EQ(Sem().Get(c_u32)->Declaration(), c_u32);
+ EXPECT_EQ(Sem().Get(c_f32)->Declaration(), c_f32);
+ EXPECT_EQ(Sem().Get(c_ai)->Declaration(), c_ai);
+ EXPECT_EQ(Sem().Get(c_af)->Declaration(), c_af);
+ EXPECT_EQ(Sem().Get(c_vi32)->Declaration(), c_vi32);
+ EXPECT_EQ(Sem().Get(c_vu32)->Declaration(), c_vu32);
+ EXPECT_EQ(Sem().Get(c_vf32)->Declaration(), c_vf32);
+ EXPECT_EQ(Sem().Get(c_vai)->Declaration(), c_vai);
+ EXPECT_EQ(Sem().Get(c_vaf)->Declaration(), c_vaf);
+ EXPECT_EQ(Sem().Get(c_mf32)->Declaration(), c_mf32);
+ EXPECT_EQ(Sem().Get(c_maf32)->Declaration(), c_maf32);
+
+ ASSERT_TRUE(TypeOf(c_i32)->Is<sem::I32>());
+ ASSERT_TRUE(TypeOf(c_u32)->Is<sem::U32>());
+ ASSERT_TRUE(TypeOf(c_f32)->Is<sem::F32>());
+ ASSERT_TRUE(TypeOf(c_ai)->Is<sem::AbstractInt>());
+ ASSERT_TRUE(TypeOf(c_af)->Is<sem::AbstractFloat>());
+ ASSERT_TRUE(TypeOf(c_vi32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vu32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vf32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vai)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vaf)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_mf32)->Is<sem::Matrix>());
+ ASSERT_TRUE(TypeOf(c_maf32)->Is<sem::Matrix>());
+
+ EXPECT_TRUE(Sem().Get(c_i32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_u32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_f32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_ai)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_af)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vi32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vu32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vf32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vai)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vaf)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_mf32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_maf32)->ConstantValue()->AllZero());
+}
+
+TEST_F(ResolverVariableTest, LocalConst_PropagateConstValue) {
+ auto* a = Const("a", nullptr, Expr(42_i));
+ auto* b = Const("b", nullptr, Expr("a"));
+ auto* c = Const("c", nullptr, Expr("b"));
+
+ WrapInFunction(a, b, c);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_TRUE(TypeOf(c)->Is<sem::I32>());
+
+ EXPECT_EQ(Sem().Get(c)->ConstantValue()->As<i32>(), 42_i);
+}
+
+// Enable when we have @const operators implemented
+TEST_F(ResolverVariableTest, DISABLED_LocalConst_ConstEval) {
+ auto* c = Const("c", nullptr, Div(Mul(Add(1_i, 2_i), 3_i), 2_i));
+
+ WrapInFunction(c);
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_TRUE(TypeOf(c)->Is<sem::I32>());
+
+ EXPECT_EQ(Sem().Get(c)->ConstantValue()->As<i32>(), 3_i);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Module-scope 'var'
+////////////////////////////////////////////////////////////////////////////////////////////////////
+TEST_F(ResolverVariableTest, GlobalVar_StorageClass) {
+ // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
+
+ auto* buf = Structure("S", {Member("m", ty.i32())});
+ auto* private_ = GlobalVar("p", ty.i32(), ast::StorageClass::kPrivate);
+ auto* workgroup = GlobalVar("w", ty.i32(), ast::StorageClass::kWorkgroup);
+ auto* uniform = GlobalVar("ub", ty.Of(buf), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
+ auto* storage = GlobalVar("sb", ty.Of(buf), ast::StorageClass::kStorage,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(0u),
+ });
+ auto* handle = GlobalVar("h", ty.depth_texture(ast::TextureDimension::k2d),
+ ast::AttributeList{
+ create<ast::BindingAttribute>(2u),
+ create<ast::GroupAttribute>(0u),
+ });
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_TRUE(TypeOf(private_)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(workgroup)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(uniform)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(storage)->Is<sem::Reference>());
+ ASSERT_TRUE(TypeOf(handle)->Is<sem::Reference>());
+
+ EXPECT_EQ(TypeOf(private_)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
+ EXPECT_EQ(TypeOf(workgroup)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
+ EXPECT_EQ(TypeOf(uniform)->As<sem::Reference>()->Access(), ast::Access::kRead);
+ EXPECT_EQ(TypeOf(storage)->As<sem::Reference>()->Access(), ast::Access::kRead);
+ EXPECT_EQ(TypeOf(handle)->As<sem::Reference>()->Access(), ast::Access::kRead);
+}
+
+TEST_F(ResolverVariableTest, GlobalVar_ExplicitStorageClass) {
+ // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
+
+ auto* buf = Structure("S", {Member("m", ty.i32())});
+ auto* storage =
+ GlobalVar("sb", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(0u),
+ });
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_TRUE(TypeOf(storage)->Is<sem::Reference>());
+
+ EXPECT_EQ(TypeOf(storage)->As<sem::Reference>()->Access(), ast::Access::kReadWrite);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Module-scope const
+////////////////////////////////////////////////////////////////////////////////////////////////////
+TEST_F(ResolverVariableTest, GlobalConst_ExplicitType_Decls) {
+ auto* c_i32 = GlobalConst("a", ty.i32(), Expr(0_i));
+ auto* c_u32 = GlobalConst("b", ty.u32(), Expr(0_u));
+ auto* c_f32 = GlobalConst("c", ty.f32(), Expr(0_f));
+ auto* c_vi32 = GlobalConst("d", ty.vec3<i32>(), vec3<i32>());
+ auto* c_vu32 = GlobalConst("e", ty.vec3<u32>(), vec3<u32>());
+ auto* c_vf32 = GlobalConst("f", ty.vec3<f32>(), vec3<f32>());
+ auto* c_mf32 = GlobalConst("g", ty.mat3x3<f32>(), mat3x3<f32>());
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ EXPECT_EQ(Sem().Get(c_i32)->Declaration(), c_i32);
+ EXPECT_EQ(Sem().Get(c_u32)->Declaration(), c_u32);
+ EXPECT_EQ(Sem().Get(c_f32)->Declaration(), c_f32);
+ EXPECT_EQ(Sem().Get(c_vi32)->Declaration(), c_vi32);
+ EXPECT_EQ(Sem().Get(c_vu32)->Declaration(), c_vu32);
+ EXPECT_EQ(Sem().Get(c_vf32)->Declaration(), c_vf32);
+ EXPECT_EQ(Sem().Get(c_mf32)->Declaration(), c_mf32);
+
+ ASSERT_TRUE(TypeOf(c_i32)->Is<sem::I32>());
+ ASSERT_TRUE(TypeOf(c_u32)->Is<sem::U32>());
+ ASSERT_TRUE(TypeOf(c_f32)->Is<sem::F32>());
+ ASSERT_TRUE(TypeOf(c_vi32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vu32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vf32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_mf32)->Is<sem::Matrix>());
+
+ EXPECT_TRUE(Sem().Get(c_i32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_u32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_f32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vi32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vu32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vf32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_mf32)->ConstantValue()->AllZero());
+}
+
+TEST_F(ResolverVariableTest, GlobalConst_ImplicitType_Decls) {
+ auto* c_i32 = GlobalConst("a", nullptr, Expr(0_i));
+ auto* c_u32 = GlobalConst("b", nullptr, Expr(0_u));
+ auto* c_f32 = GlobalConst("c", nullptr, Expr(0_f));
+ auto* c_ai = GlobalConst("d", nullptr, Expr(0_a));
+ auto* c_af = GlobalConst("e", nullptr, Expr(0._a));
+ auto* c_vi32 = GlobalConst("f", nullptr, vec3<i32>());
+ auto* c_vu32 = GlobalConst("g", nullptr, vec3<u32>());
+ auto* c_vf32 = GlobalConst("h", nullptr, vec3<f32>());
+ auto* c_vai = GlobalConst("i", nullptr, Construct(ty.vec(nullptr, 3), Expr(0_a)));
+ auto* c_vaf = GlobalConst("j", nullptr, Construct(ty.vec(nullptr, 3), Expr(0._a)));
+ auto* c_mf32 = GlobalConst("k", nullptr, mat3x3<f32>());
+ auto* c_maf32 = GlobalConst("l", nullptr,
+ Construct(ty.mat(nullptr, 3, 3), //
+ Construct(ty.vec(nullptr, 3), Expr(0._a)),
+ Construct(ty.vec(nullptr, 3), Expr(0._a)),
+ Construct(ty.vec(nullptr, 3), Expr(0._a))));
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ EXPECT_EQ(Sem().Get(c_i32)->Declaration(), c_i32);
+ EXPECT_EQ(Sem().Get(c_u32)->Declaration(), c_u32);
+ EXPECT_EQ(Sem().Get(c_f32)->Declaration(), c_f32);
+ EXPECT_EQ(Sem().Get(c_ai)->Declaration(), c_ai);
+ EXPECT_EQ(Sem().Get(c_af)->Declaration(), c_af);
+ EXPECT_EQ(Sem().Get(c_vi32)->Declaration(), c_vi32);
+ EXPECT_EQ(Sem().Get(c_vu32)->Declaration(), c_vu32);
+ EXPECT_EQ(Sem().Get(c_vf32)->Declaration(), c_vf32);
+ EXPECT_EQ(Sem().Get(c_vai)->Declaration(), c_vai);
+ EXPECT_EQ(Sem().Get(c_vaf)->Declaration(), c_vaf);
+ EXPECT_EQ(Sem().Get(c_mf32)->Declaration(), c_mf32);
+ EXPECT_EQ(Sem().Get(c_maf32)->Declaration(), c_maf32);
+
+ ASSERT_TRUE(TypeOf(c_i32)->Is<sem::I32>());
+ ASSERT_TRUE(TypeOf(c_u32)->Is<sem::U32>());
+ ASSERT_TRUE(TypeOf(c_f32)->Is<sem::F32>());
+ ASSERT_TRUE(TypeOf(c_ai)->Is<sem::AbstractInt>());
+ ASSERT_TRUE(TypeOf(c_af)->Is<sem::AbstractFloat>());
+ ASSERT_TRUE(TypeOf(c_vi32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vu32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vf32)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vai)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_vaf)->Is<sem::Vector>());
+ ASSERT_TRUE(TypeOf(c_mf32)->Is<sem::Matrix>());
+ ASSERT_TRUE(TypeOf(c_maf32)->Is<sem::Matrix>());
+
+ EXPECT_TRUE(Sem().Get(c_i32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_u32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_f32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_ai)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_af)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vi32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vu32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vf32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vai)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_vaf)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_mf32)->ConstantValue()->AllZero());
+ EXPECT_TRUE(Sem().Get(c_maf32)->ConstantValue()->AllZero());
+}
+
+TEST_F(ResolverVariableTest, GlobalConst_PropagateConstValue) {
+ GlobalConst("b", nullptr, Expr("a"));
+ auto* c = GlobalConst("c", nullptr, Expr("b"));
+ GlobalConst("a", nullptr, Expr(42_i));
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_TRUE(TypeOf(c)->Is<sem::I32>());
+
+ EXPECT_EQ(Sem().Get(c)->ConstantValue()->As<i32>(), 42_i);
+}
+
+// Enable when we have @const operators implemented
+TEST_F(ResolverVariableTest, DISABLED_GlobalConst_ConstEval) {
+ auto* c = GlobalConst("c", nullptr, Div(Mul(Add(1_i, 2_i), 3_i), 2_i));
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_TRUE(TypeOf(c)->Is<sem::I32>());
+
+ EXPECT_EQ(Sem().Get(c)->ConstantValue()->As<i32>(), 3_i);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Function parameter
+////////////////////////////////////////////////////////////////////////////////////////////////////
+TEST_F(ResolverVariableTest, Param_ShadowsFunction) {
+ // fn a(a : bool) {
+ // }
+
+ auto* p = Param("a", ty.bool_());
+ auto* f = Func("a", {p}, ty.void_(), {});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* func = Sem().Get(f);
+ auto* param = Sem().Get<sem::Parameter>(p);
+
+ ASSERT_NE(func, nullptr);
+ ASSERT_NE(param, nullptr);
+
+ EXPECT_EQ(param->Shadows(), func);
+}
+
+TEST_F(ResolverVariableTest, Param_ShadowsGlobalVar) {
+ // var<private> a : i32;
+ //
+ // fn F(a : bool) {
+ // }
+
+ auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+ auto* p = Param("a", ty.bool_());
+ Func("F", {p}, ty.void_(), {});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* global = Sem().Get(g);
+ auto* param = Sem().Get<sem::Parameter>(p);
+
+ ASSERT_NE(global, nullptr);
+ ASSERT_NE(param, nullptr);
+
+ EXPECT_EQ(param->Shadows(), global);
+}
+
+TEST_F(ResolverVariableTest, Param_ShadowsGlobalConst) {
+ // const a : i32 = 1i;
+ //
+ // fn F(a : bool) {
+ // }
+
+ auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
+ auto* p = Param("a", ty.bool_());
+ Func("F", {p}, ty.void_(), {});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* global = Sem().Get(g);
+ auto* param = Sem().Get<sem::Parameter>(p);
+
+ ASSERT_NE(global, nullptr);
+ ASSERT_NE(param, nullptr);
+
+ EXPECT_EQ(param->Shadows(), global);
+}
+
+TEST_F(ResolverVariableTest, Param_ShadowsAlias) {
+ // type a = i32;
+ //
+ // fn F(a : a) {
+ // }
+
+ auto* a = Alias("a", ty.i32());
+ auto* p = Param("a", ty.type_name("a"));
+ Func("F", {p}, ty.void_(), {});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* alias = Sem().Get(a);
+ auto* param = Sem().Get<sem::Parameter>(p);
+
+ ASSERT_NE(alias, nullptr);
+ ASSERT_NE(param, nullptr);
+
+ EXPECT_EQ(param->Shadows(), alias);
+ EXPECT_EQ(param->Type(), alias);
+}
+
+} // namespace
+} // namespace tint::resolver
diff --git a/src/tint/resolver/variable_validation_test.cc b/src/tint/resolver/variable_validation_test.cc
new file mode 100644
index 0000000..79b269c
--- /dev/null
+++ b/src/tint/resolver/variable_validation_test.cc
@@ -0,0 +1,413 @@
+// Copyright 2021 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/resolver/resolver.h"
+#include "src/tint/resolver/resolver_test_helper.h"
+
+#include "gmock/gmock.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::resolver {
+namespace {
+
+struct ResolverVariableValidationTest : public resolver::TestHelper, public testing::Test {};
+
+TEST_F(ResolverVariableValidationTest, VarNoInitializerNoType) {
+ // var a;
+ WrapInFunction(Var(Source{{12, 34}}, "a", nullptr));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: var declaration requires a type or initializer");
+}
+
+TEST_F(ResolverVariableValidationTest, GlobalVarNoInitializerNoType) {
+ // var a;
+ GlobalVar(Source{{12, 34}}, "a", nullptr);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: var declaration requires a type or initializer");
+}
+
+TEST_F(ResolverVariableValidationTest, GlobalVarUsedAtModuleScope) {
+ // var<private> a : i32;
+ // var<private> b : i32 = a;
+ GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::StorageClass::kPrivate, nullptr);
+ GlobalVar("b", ty.i32(), ast::StorageClass::kPrivate, Expr(Source{{56, 78}}, "a"));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), R"(56:78 error: var 'a' cannot not be referenced at module-scope
+12:34 note: var 'a' declared here)");
+}
+
+TEST_F(ResolverVariableValidationTest, OverrideNoInitializerNoType) {
+ // override a;
+ Override(Source{{12, 34}}, "a", nullptr, nullptr);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: override declaration requires a type or initializer");
+}
+
+TEST_F(ResolverVariableValidationTest, VarTypeNotStorable) {
+ // var i : i32;
+ // var p : pointer<function, i32> = &v;
+ auto* i = Var("i", ty.i32(), ast::StorageClass::kNone);
+ auto* p = Var(Source{{56, 78}}, "a", ty.pointer<i32>(ast::StorageClass::kFunction),
+ ast::StorageClass::kNone, AddressOf(Source{{12, 34}}, "i"));
+ WrapInFunction(i, p);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "56:78 error: ptr<function, i32, read_write> cannot be used as the "
+ "type of a var");
+}
+
+TEST_F(ResolverVariableValidationTest, LetTypeNotConstructible) {
+ // @group(0) @binding(0) var t1 : texture_2d<f32>;
+ // let t2 : t1;
+ auto* t1 = GlobalVar("t1", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+ GroupAndBinding(0, 0));
+ auto* t2 = Let(Source{{56, 78}}, "t2", nullptr, Expr(t1));
+ WrapInFunction(t2);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "56:78 error: texture_2d<f32> cannot be used as the type of a 'let'");
+}
+
+TEST_F(ResolverVariableValidationTest, OverrideExplicitTypeNotScalar) {
+ // override o : vec3<f32>;
+ Override(Source{{56, 78}}, "o", ty.vec3<f32>(), nullptr);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "56:78 error: vec3<f32> cannot be used as the type of a 'override'");
+}
+
+TEST_F(ResolverVariableValidationTest, OverrideInferedTypeNotScalar) {
+ // override o = vec3(1.0f);
+ Override(Source{{56, 78}}, "o", nullptr, vec3<f32>(1.0_f));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "56:78 error: vec3<f32> cannot be used as the type of a 'override'");
+}
+
+TEST_F(ResolverVariableValidationTest, ConstConstructorWrongType) {
+ // const c : i32 = 2u
+ WrapInFunction(Const(Source{{3, 3}}, "c", ty.i32(), Expr(2_u)));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(3:3 error: cannot initialize const of type 'i32' with value of type 'u32')");
+}
+
+TEST_F(ResolverVariableValidationTest, LetConstructorWrongType) {
+ // var v : i32 = 2u
+ WrapInFunction(Let(Source{{3, 3}}, "v", ty.i32(), Expr(2_u)));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(3:3 error: cannot initialize let of type 'i32' with value of type 'u32')");
+}
+
+TEST_F(ResolverVariableValidationTest, VarConstructorWrongType) {
+ // var v : i32 = 2u
+ WrapInFunction(Var(Source{{3, 3}}, "v", ty.i32(), ast::StorageClass::kNone, Expr(2_u)));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(3:3 error: cannot initialize var of type 'i32' with value of type 'u32')");
+}
+
+TEST_F(ResolverVariableValidationTest, ConstConstructorWrongTypeViaAlias) {
+ auto* a = Alias("I32", ty.i32());
+ WrapInFunction(Const(Source{{3, 3}}, "v", ty.Of(a), Expr(2_u)));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(3:3 error: cannot initialize const of type 'i32' with value of type 'u32')");
+}
+
+TEST_F(ResolverVariableValidationTest, LetConstructorWrongTypeViaAlias) {
+ auto* a = Alias("I32", ty.i32());
+ WrapInFunction(Let(Source{{3, 3}}, "v", ty.Of(a), Expr(2_u)));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(3:3 error: cannot initialize let of type 'i32' with value of type 'u32')");
+}
+
+TEST_F(ResolverVariableValidationTest, VarConstructorWrongTypeViaAlias) {
+ auto* a = Alias("I32", ty.i32());
+ WrapInFunction(Var(Source{{3, 3}}, "v", ty.Of(a), ast::StorageClass::kNone, Expr(2_u)));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(3:3 error: cannot initialize var of type 'i32' with value of type 'u32')");
+}
+
+TEST_F(ResolverVariableValidationTest, LetOfPtrConstructedWithRef) {
+ // var a : f32;
+ // let b : ptr<function,f32> = a;
+ const auto priv = ast::StorageClass::kFunction;
+ auto* var_a = Var("a", ty.f32(), priv);
+ auto* var_b = Let(Source{{12, 34}}, "b", ty.pointer<f32>(priv), Expr("a"), {});
+ WrapInFunction(var_a, var_b);
+
+ ASSERT_FALSE(r()->Resolve());
+
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: cannot initialize let of type 'ptr<function, f32, read_write>' with value of type 'f32')");
+}
+
+TEST_F(ResolverVariableValidationTest, LocalLetRedeclared) {
+ // let l : f32 = 1.;
+ // let l : i32 = 0;
+ auto* l1 = Let("l", ty.f32(), Expr(1_f));
+ auto* l2 = Let(Source{{12, 34}}, "l", ty.i32(), Expr(0_i));
+ WrapInFunction(l1, l2);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "12:34 error: redeclaration of 'l'\nnote: 'l' previously declared here");
+}
+
+TEST_F(ResolverVariableValidationTest, GlobalVarRedeclaredAsLocal) {
+ // var v : f32 = 2.1;
+ // fn my_func() {
+ // var v : f32 = 2.0;
+ // return 0;
+ // }
+
+ GlobalVar("v", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
+
+ WrapInFunction(Var(Source{{12, 34}}, "v", ty.f32(), ast::StorageClass::kNone, Expr(2_f)));
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverVariableValidationTest, VarRedeclaredInInnerBlock) {
+ // {
+ // var v : f32;
+ // { var v : f32; }
+ // }
+ auto* var_outer = Var("v", ty.f32(), ast::StorageClass::kNone);
+ auto* var_inner = Var(Source{{12, 34}}, "v", ty.f32(), ast::StorageClass::kNone);
+ auto* inner = Block(Decl(var_inner));
+ auto* outer_body = Block(Decl(var_outer), inner);
+
+ WrapInFunction(outer_body);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverVariableValidationTest, VarRedeclaredInIfBlock) {
+ // {
+ // var v : f32 = 3.14;
+ // if (true) { var v : f32 = 2.0; }
+ // }
+ auto* var_a_float = Var("v", ty.f32(), ast::StorageClass::kNone, Expr(3.1_f));
+
+ auto* var = Var(Source{{12, 34}}, "v", ty.f32(), ast::StorageClass::kNone, Expr(2_f));
+
+ auto* cond = Expr(true);
+ auto* body = Block(Decl(var));
+
+ auto* outer_body = Block(Decl(var_a_float), If(cond, body));
+
+ WrapInFunction(outer_body);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverVariableValidationTest, InferredPtrStorageAccessMismatch) {
+ // struct Inner {
+ // arr: array<i32, 4>;
+ // }
+ // struct S {
+ // inner: Inner;
+ // }
+ // @group(0) @binding(0) var<storage> s : S;
+ // fn f() {
+ // let p : pointer<storage, i32, read_write> = &s.inner.arr[2i];
+ // }
+ auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
+ auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
+ auto* storage = GlobalVar("s", ty.Of(buf), ast::StorageClass::kStorage,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
+
+ auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 2_i);
+ auto* ptr =
+ Let(Source{{12, 34}}, "p",
+ ty.pointer<i32>(ast::StorageClass::kStorage, ast::Access::kReadWrite), AddressOf(expr));
+
+ WrapInFunction(ptr);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "12:34 error: cannot initialize let of type "
+ "'ptr<storage, i32, read_write>' with value of type "
+ "'ptr<storage, i32, read>'");
+}
+
+TEST_F(ResolverVariableValidationTest, NonConstructibleType_Atomic) {
+ auto* v = Var("v", ty.atomic(Source{{12, 34}}, ty.i32()));
+ WrapInFunction(v);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: function-scope 'var' must have a constructible type");
+}
+
+TEST_F(ResolverVariableValidationTest, NonConstructibleType_RuntimeArray) {
+ auto* s = Structure("S", {Member(Source{{56, 78}}, "m", ty.array(ty.i32()))});
+ auto* v = Var(Source{{12, 34}}, "v", ty.Of(s));
+ WrapInFunction(v);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+56:78 note: while analysing structure member S.m
+12:34 note: while instantiating 'var' v)");
+}
+
+TEST_F(ResolverVariableValidationTest, NonConstructibleType_Struct_WithAtomic) {
+ auto* s = Structure("S", {Member("m", ty.atomic(ty.i32()))});
+ auto* v = Var("v", ty.Of(s));
+ WrapInFunction(v);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "error: function-scope 'var' must have a constructible type");
+}
+
+TEST_F(ResolverVariableValidationTest, NonConstructibleType_InferredType) {
+ // @group(0) @binding(0) var s : sampler;
+ // fn foo() {
+ // var v = s;
+ // }
+ GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), GroupAndBinding(0, 0));
+ auto* v = Var(Source{{12, 34}}, "v", nullptr, Expr("s"));
+ WrapInFunction(v);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: function-scope 'var' must have a constructible type");
+}
+
+TEST_F(ResolverVariableValidationTest, InvalidStorageClassForInitializer) {
+ // var<workgroup> v : f32 = 1.23;
+ GlobalVar(Source{{12, 34}}, "v", ty.f32(), ast::StorageClass::kWorkgroup, Expr(1.23_f));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "12:34 error: var of storage class 'workgroup' cannot have "
+ "an initializer. var initializers are only supported for the "
+ "storage classes 'private' and 'function'");
+}
+
+TEST_F(ResolverVariableValidationTest, VectorConstNoType) {
+ // const a : mat3x3 = mat3x3<f32>();
+ WrapInFunction(Const("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3u), vec3<f32>()));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
+}
+
+TEST_F(ResolverVariableValidationTest, VectorLetNoType) {
+ // let a : mat3x3 = mat3x3<f32>();
+ WrapInFunction(Let("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3u), vec3<f32>()));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
+}
+
+TEST_F(ResolverVariableValidationTest, VectorVarNoType) {
+ // var a : mat3x3;
+ WrapInFunction(Var("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3u)));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
+}
+
+TEST_F(ResolverVariableValidationTest, MatrixConstNoType) {
+ // const a : mat3x3 = mat3x3<f32>();
+ WrapInFunction(
+ Const("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3u, 3u), mat3x3<f32>()));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
+}
+
+TEST_F(ResolverVariableValidationTest, MatrixLetNoType) {
+ // let a : mat3x3 = mat3x3<f32>();
+ WrapInFunction(Let("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3u, 3u), mat3x3<f32>()));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
+}
+
+TEST_F(ResolverVariableValidationTest, MatrixVarNoType) {
+ // var a : mat3x3;
+ WrapInFunction(Var("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3u, 3u)));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
+}
+
+TEST_F(ResolverVariableValidationTest, ConstStructure) {
+ auto* s = Structure("S", {Member("m", ty.i32())});
+ auto* c = Const("c", ty.Of(s), Construct(Source{{12, 34}}, ty.Of(s)));
+ WrapInFunction(c);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), R"(12:34 error: 'const' initializer must be constant expression)");
+}
+
+TEST_F(ResolverVariableValidationTest, GlobalConstStructure) {
+ auto* s = Structure("S", {Member("m", ty.i32())});
+ GlobalConst("c", ty.Of(s), Construct(Source{{12, 34}}, ty.Of(s)));
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), R"(12:34 error: 'const' initializer must be constant expression)");
+}
+
+TEST_F(ResolverVariableValidationTest, ConstInitWithVar) {
+ auto* v = Var("v", nullptr, Expr(1_i));
+ auto* c = Const("c", nullptr, Expr(Source{{12, 34}}, v));
+ WrapInFunction(v, c);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), R"(12:34 error: 'const' initializer must be constant expression)");
+}
+
+TEST_F(ResolverVariableValidationTest, ConstInitWithOverride) {
+ auto* o = Override("v", nullptr, Expr(1_i));
+ auto* c = Const("c", nullptr, Expr(Source{{12, 34}}, o));
+ WrapInFunction(c);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), R"(12:34 error: 'const' initializer must be constant expression)");
+}
+
+TEST_F(ResolverVariableValidationTest, ConstInitWithLet) {
+ auto* l = Let("v", nullptr, Expr(1_i));
+ auto* c = Const("c", nullptr, Expr(Source{{12, 34}}, l));
+ WrapInFunction(l, c);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), R"(12:34 error: 'const' initializer must be constant expression)");
+}
+
+} // namespace
+} // namespace tint::resolver
diff --git a/src/tint/sem/builtin_type.cc b/src/tint/sem/builtin_type.cc
index c95ce19..1888d0b 100644
--- a/src/tint/sem/builtin_type.cc
+++ b/src/tint/sem/builtin_type.cc
@@ -35,6 +35,9 @@
if (name == "acos") {
return BuiltinType::kAcos;
}
+ if (name == "acosh") {
+ return BuiltinType::kAcosh;
+ }
if (name == "all") {
return BuiltinType::kAll;
}
@@ -47,12 +50,18 @@
if (name == "asin") {
return BuiltinType::kAsin;
}
+ if (name == "asinh") {
+ return BuiltinType::kAsinh;
+ }
if (name == "atan") {
return BuiltinType::kAtan;
}
if (name == "atan2") {
return BuiltinType::kAtan2;
}
+ if (name == "atanh") {
+ return BuiltinType::kAtanh;
+ }
if (name == "ceil") {
return BuiltinType::kCeil;
}
@@ -358,6 +367,8 @@
return "abs";
case BuiltinType::kAcos:
return "acos";
+ case BuiltinType::kAcosh:
+ return "acosh";
case BuiltinType::kAll:
return "all";
case BuiltinType::kAny:
@@ -366,10 +377,14 @@
return "arrayLength";
case BuiltinType::kAsin:
return "asin";
+ case BuiltinType::kAsinh:
+ return "asinh";
case BuiltinType::kAtan:
return "atan";
case BuiltinType::kAtan2:
return "atan2";
+ case BuiltinType::kAtanh:
+ return "atanh";
case BuiltinType::kCeil:
return "ceil";
case BuiltinType::kClamp:
diff --git a/src/tint/sem/builtin_type.h b/src/tint/sem/builtin_type.h
index a119d79..caf7c53 100644
--- a/src/tint/sem/builtin_type.h
+++ b/src/tint/sem/builtin_type.h
@@ -35,12 +35,15 @@
kNone = -1,
kAbs,
kAcos,
+ kAcosh,
kAll,
kAny,
kArrayLength,
kAsin,
+ kAsinh,
kAtan,
kAtan2,
+ kAtanh,
kCeil,
kClamp,
kCos,
diff --git a/src/tint/sem/call.cc b/src/tint/sem/call.cc
index f688cce..bfce3b1 100644
--- a/src/tint/sem/call.cc
+++ b/src/tint/sem/call.cc
@@ -25,9 +25,9 @@
const CallTarget* target,
std::vector<const sem::Expression*> arguments,
const Statement* statement,
- Constant constant,
+ const Constant* constant,
bool has_side_effects)
- : Base(declaration, target->ReturnType(), statement, std::move(constant), has_side_effects),
+ : Base(declaration, target->ReturnType(), statement, constant, has_side_effects),
target_(target),
arguments_(std::move(arguments)) {}
diff --git a/src/tint/sem/call.h b/src/tint/sem/call.h
index c96179d..1955bf9 100644
--- a/src/tint/sem/call.h
+++ b/src/tint/sem/call.h
@@ -17,6 +17,7 @@
#include <vector>
+#include "src/tint/ast/call_expression.h"
#include "src/tint/sem/builtin.h"
#include "src/tint/sem/expression.h"
@@ -37,7 +38,7 @@
const CallTarget* target,
std::vector<const sem::Expression*> arguments,
const Statement* statement,
- Constant constant,
+ const Constant* constant,
bool has_side_effects);
/// Destructor
diff --git a/src/tint/sem/constant.cc b/src/tint/sem/constant.cc
index 8086992..70bb08c 100644
--- a/src/tint/sem/constant.cc
+++ b/src/tint/sem/constant.cc
@@ -14,100 +14,10 @@
#include "src/tint/sem/constant.h"
-#include <cmath>
-#include <utility>
-
-#include "src/tint/debug.h"
-#include "src/tint/program_builder.h"
-#include "src/tint/sem/type.h"
-
namespace tint::sem {
-namespace {
-size_t CountElements(const Constant::Elements& elements) {
- return std::visit([](auto&& vec) { return vec.size(); }, elements);
-}
-
-template <typename T>
-bool IsNegativeFloat(T value) {
- (void)value;
- if constexpr (IsFloatingPoint<T>) {
- return std::signbit(value);
- } else {
- return false;
- }
-}
-
-} // namespace
-
-Constant::Constant() {}
-
-Constant::Constant(const sem::Type* ty, Elements els)
- : type_(ty), elem_type_(CheckElemType(ty, CountElements(els))), elems_(std::move(els)) {}
-
-Constant::Constant(const sem::Type* ty, AInts vec) : Constant(ty, Elements{std::move(vec)}) {}
-
-Constant::Constant(const sem::Type* ty, AFloats vec) : Constant(ty, Elements{std::move(vec)}) {}
-
-Constant::Constant(const Constant&) = default;
+Constant::Constant() = default;
Constant::~Constant() = default;
-Constant& Constant::operator=(const Constant& rhs) = default;
-
-bool Constant::AnyZero() const {
- return WithElements([&](auto&& vec) {
- using T = typename std::decay_t<decltype(vec)>::value_type;
- for (auto el : vec) {
- if (el == T(0) && !IsNegativeFloat(el.value)) {
- return true;
- }
- }
- return false;
- });
-}
-
-bool Constant::AllZero() const {
- return WithElements([&](auto&& vec) {
- using T = typename std::decay_t<decltype(vec)>::value_type;
- for (auto el : vec) {
- if (el != T(0) || IsNegativeFloat(el.value)) {
- return false;
- }
- }
- return true;
- });
-}
-
-bool Constant::AllEqual(size_t start, size_t end) const {
- return WithElements([&](auto&& vec) {
- if (!vec.empty()) {
- auto value = vec[start];
- bool float_sign = IsNegativeFloat(vec[start].value);
- for (size_t i = start + 1; i < end; i++) {
- if (vec[i] != value || float_sign != IsNegativeFloat(vec[i].value)) {
- return false;
- }
- }
- }
- return true;
- });
-}
-
-const Type* Constant::CheckElemType(const sem::Type* ty, size_t num_elements) {
- diag::List diag;
- if (ty->is_abstract_or_scalar() || ty->IsAnyOf<Vector, Matrix>()) {
- uint32_t count = 0;
- auto* el_ty = Type::ElementOf(ty, &count);
- if (num_elements != count) {
- TINT_ICE(Semantic, diag) << "sem::Constant() type <-> element mismatch. type: '"
- << ty->TypeInfo().name << "' element: " << num_elements;
- }
- TINT_ASSERT(Semantic, el_ty->is_abstract_or_scalar());
- return el_ty;
- }
- TINT_UNREACHABLE(Semantic, diag) << "Unsupported sem::Constant type: " << ty->TypeInfo().name;
- return nullptr;
-}
-
} // namespace tint::sem
diff --git a/src/tint/sem/constant.h b/src/tint/sem/constant.h
index 4f7132a..b46127c 100644
--- a/src/tint/sem/constant.h
+++ b/src/tint/sem/constant.h
@@ -15,172 +15,64 @@
#ifndef SRC_TINT_SEM_CONSTANT_H_
#define SRC_TINT_SEM_CONSTANT_H_
-#include <ostream>
-#include <utility>
#include <variant>
-#include <vector>
-#include "src/tint/program_builder.h"
-#include "src/tint/sem/type.h"
+#include "src/tint/number.h"
+
+// Forward declarations
+namespace tint::sem {
+class Type;
+}
namespace tint::sem {
-/// A Constant holds a compile-time evaluated expression value, expressed as a flattened list of
-/// element values. The expression type may be of an abstract-numeric, scalar, vector or matrix
-/// type. Constant holds the element values in either a vector of abstract-integer (AInt) or
-/// abstract-float (AFloat), depending on the element type.
+/// Constant is the interface to a compile-time evaluated expression value.
class Constant {
public:
- /// AInts is a vector of AInt, used to hold elements of the WGSL types:
- /// * abstract-integer
- /// * i32
- /// * u32
- /// * bool (0 or 1)
- using AInts = std::vector<AInt>;
-
- /// AFloats is a vector of AFloat, used to hold elements of the WGSL types:
- /// * abstract-float
- /// * f32
- /// * f16
- using AFloats = std::vector<AFloat>;
-
- /// Elements is either a vector of AInts or AFloats
- using Elements = std::variant<AInts, AFloats>;
-
- /// Helper that resolves to either AInt or AFloat based on the element type T.
- template <typename T>
- using ElementFor = std::conditional_t<IsFloatingPoint<UnwrapNumber<T>>, AFloat, AInt>;
-
- /// Helper that resolves to either AInts or AFloats based on the element type T.
- template <typename T>
- using ElementVectorFor = std::conditional_t<IsFloatingPoint<UnwrapNumber<T>>, AFloats, AInts>;
-
- /// Constructs an invalid Constant
+ /// Constructor
Constant();
- /// Constructs a Constant of the given type and element values
- /// @param ty the Constant type
- /// @param els the Constant element values
- Constant(const sem::Type* ty, Elements els);
-
- /// Constructs a Constant of the given type and element values
- /// @param ty the Constant type
- /// @param vec the Constant element values
- Constant(const sem::Type* ty, AInts vec);
-
- /// Constructs a Constant of the given type and element values
- /// @param ty the Constant type
- /// @param vec the Constant element values
- Constant(const sem::Type* ty, AFloats vec);
-
- /// Constructs a Constant of the given type and element values
- /// @param ty the Constant type
- /// @param els the Constant element values
- template <typename T>
- Constant(const sem::Type* ty, std::initializer_list<T> els);
-
- /// Copy constructor
- Constant(const Constant&);
-
/// Destructor
- ~Constant();
+ virtual ~Constant();
- /// Copy assignment
- /// @param other the Constant to copy
- /// @returns this Constant
- Constant& operator=(const Constant& other);
+ /// @returns the type of the constant
+ virtual const sem::Type* Type() const = 0;
- /// @returns true if the Constant has been initialized
- bool IsValid() const { return type_ != nullptr; }
+ /// @returns the value of this Constant, if this constant is of a scalar value or abstract
+ /// numeric, otherwsie std::monostate.
+ virtual std::variant<std::monostate, AInt, AFloat> Value() const = 0;
- /// @return true if the Constant has been initialized
- operator bool() const { return IsValid(); }
+ /// @returns the child constant element with the given index, or nullptr if the constant has no
+ /// children, or the index is out of bounds.
+ virtual const Constant* Index(size_t) const = 0;
- /// @returns the type of the Constant
- const sem::Type* Type() const { return type_; }
+ /// @returns true if child elements of this constant are positive-zero valued.
+ virtual bool AllZero() const = 0;
- /// @returns the number of elements
- size_t ElementCount() const {
- return std::visit([](auto&& v) { return v.size(); }, elems_);
- }
+ /// @returns true if any child elements of this constant are positive-zero valued.
+ virtual bool AnyZero() const = 0;
- /// @returns the element type of the Constant
- const sem::Type* ElementType() const { return elem_type_; }
+ /// @returns true if all child elements of this constant have the same value and type.
+ virtual bool AllEqual() const = 0;
- /// @returns the constant's elements
- const Elements& GetElements() const { return elems_; }
+ /// @returns a hash of the constant.
+ virtual size_t Hash() const = 0;
- /// WithElements calls the function `f` with the vector of elements as either AFloats or AInts
- /// @param f a function-like with the signature `R(auto&&)`.
- /// @returns the result of calling `f`.
- template <typename F>
- auto WithElements(F&& f) const {
- return std::visit(std::forward<F>(f), elems_);
- }
-
- /// WithElements calls the function `f` with the element vector as either AFloats or AInts
- /// @param f a function-like with the signature `R(auto&&)`.
- /// @returns the result of calling `f`.
- template <typename F>
- auto WithElements(F&& f) {
- return std::visit(std::forward<F>(f), elems_);
- }
-
- /// @returns the elements as a vector of AInt
- inline const AInts& IElements() const { return std::get<AInts>(elems_); }
-
- /// @returns the elements as a vector of AFloat
- inline const AFloats& FElements() const { return std::get<AFloats>(elems_); }
-
- /// @returns true if any element is positive zero
- bool AnyZero() const;
-
- /// @returns true if all elements are positive zero
- bool AllZero() const;
-
- /// @returns true if all elements are the same value, with the same sign-bit.
- bool AllEqual() const { return AllEqual(0, ElementCount()); }
-
- /// @param start the first element index
- /// @param end one past the last element index
- /// @returns true if all elements between `[start, end)` are the same value
- bool AllEqual(size_t start, size_t end) const;
-
- /// @param index the index of the element
- /// @return the element at `index`, which must be of type `T`.
+ /// @returns the value of the constant as the given scalar or abstract value.
template <typename T>
- T Element(size_t index) const;
-
- private:
- /// Checks that the provided type matches the number of expected elements.
- /// @returns the element type of `ty`.
- const sem::Type* CheckElemType(const sem::Type* ty, size_t num_elements);
-
- const sem::Type* type_ = nullptr;
- const sem::Type* elem_type_ = nullptr;
- Elements elems_;
+ T As() const {
+ return std::visit(
+ [](auto v) {
+ if constexpr (std::is_same_v<decltype(v), std::monostate>) {
+ return T(0);
+ } else {
+ return static_cast<T>(v);
+ }
+ },
+ Value());
+ }
};
-template <typename T>
-Constant::Constant(const sem::Type* ty, std::initializer_list<T> els)
- : type_(ty), elem_type_(CheckElemType(type_, els.size())) {
- ElementVectorFor<T> elements;
- elements.reserve(els.size());
- for (auto el : els) {
- elements.emplace_back(ElementFor<T>(el));
- }
- elems_ = Elements{std::move(elements)};
-}
-
-template <typename T>
-T Constant::Element(size_t index) const {
- if constexpr (std::is_same_v<ElementVectorFor<T>, AFloats>) {
- return static_cast<T>(FElements()[index].value);
- } else {
- return static_cast<T>(IElements()[index].value);
- }
-}
-
} // namespace tint::sem
#endif // SRC_TINT_SEM_CONSTANT_H_
diff --git a/src/tint/sem/constant_test.cc b/src/tint/sem/constant_test.cc
deleted file mode 100644
index ed9fef8..0000000
--- a/src/tint/sem/constant_test.cc
+++ /dev/null
@@ -1,304 +0,0 @@
-// 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/sem/constant.h"
-
-#include <gmock/gmock.h>
-
-#include "src/tint/sem/abstract_float.h"
-#include "src/tint/sem/abstract_int.h"
-#include "src/tint/sem/test_helper.h"
-
-using namespace tint::number_suffixes; // NOLINT
-
-namespace tint::sem {
-namespace {
-
-using ConstantTest = TestHelper;
-
-TEST_F(ConstantTest, ConstructorInitializerList) {
- {
- auto i = AInt(AInt::kHighest);
- Constant c(create<AbstractInt>(), {i});
- c.WithElements([&](auto&& vec) { EXPECT_THAT(vec, testing::ElementsAre(i)); });
- }
- {
- auto i = i32(i32::kHighest);
- Constant c(create<I32>(), {i});
- c.WithElements([&](auto&& vec) { EXPECT_THAT(vec, testing::ElementsAre(i)); });
- }
- {
- auto i = u32(u32::kHighest);
- Constant c(create<U32>(), {i});
- c.WithElements([&](auto&& vec) { EXPECT_THAT(vec, testing::ElementsAre(i)); });
- }
- {
- Constant c(create<Bool>(), {false});
- c.WithElements([&](auto&& vec) { EXPECT_THAT(vec, testing::ElementsAre(0_a)); });
- }
- {
- Constant c(create<Bool>(), {true});
- c.WithElements([&](auto&& vec) { EXPECT_THAT(vec, testing::ElementsAre(1_a)); });
- }
- {
- auto f = AFloat(AFloat::kHighest);
- Constant c(create<AbstractFloat>(), {f});
- c.WithElements([&](auto&& vec) { EXPECT_THAT(vec, testing::ElementsAre(f)); });
- }
- {
- auto f = f32(f32::kHighest);
- Constant c(create<F32>(), {f});
- c.WithElements([&](auto&& vec) { EXPECT_THAT(vec, testing::ElementsAre(f)); });
- }
- {
- auto f = f16(f16::kHighest);
- Constant c(create<F16>(), {f});
- c.WithElements([&](auto&& vec) { EXPECT_THAT(vec, testing::ElementsAre(f)); });
- }
-}
-
-TEST_F(ConstantTest, Element_ai) {
- Constant c(create<AbstractInt>(), {1_a});
- EXPECT_EQ(c.Element<AInt>(0), 1_a);
- EXPECT_EQ(c.ElementCount(), 1u);
-}
-
-TEST_F(ConstantTest, Element_i32) {
- Constant c(create<I32>(), {1_a});
- EXPECT_EQ(c.Element<i32>(0), 1_i);
- EXPECT_EQ(c.ElementCount(), 1u);
-}
-
-TEST_F(ConstantTest, Element_u32) {
- Constant c(create<U32>(), {1_a});
- EXPECT_EQ(c.Element<u32>(0), 1_u);
- EXPECT_EQ(c.ElementCount(), 1u);
-}
-
-TEST_F(ConstantTest, Element_bool) {
- Constant c(create<Bool>(), {true});
- EXPECT_EQ(c.Element<bool>(0), true);
- EXPECT_EQ(c.ElementCount(), 1u);
-}
-
-TEST_F(ConstantTest, Element_af) {
- Constant c(create<AbstractFloat>(), {1.0_a});
- EXPECT_EQ(c.Element<AFloat>(0), 1.0_a);
- EXPECT_EQ(c.ElementCount(), 1u);
-}
-
-TEST_F(ConstantTest, Element_f32) {
- Constant c(create<F32>(), {1.0_a});
- EXPECT_EQ(c.Element<f32>(0), 1.0_f);
- EXPECT_EQ(c.ElementCount(), 1u);
-}
-
-TEST_F(ConstantTest, Element_f16) {
- Constant c(create<F16>(), {1.0_a});
- EXPECT_EQ(c.Element<f16>(0), 1.0_h);
- EXPECT_EQ(c.ElementCount(), 1u);
-}
-
-TEST_F(ConstantTest, Element_vec3_ai) {
- Constant c(create<Vector>(create<AbstractInt>(), 3u), {1_a, 2_a, 3_a});
- EXPECT_EQ(c.Element<AInt>(0), 1_a);
- EXPECT_EQ(c.Element<AInt>(1), 2_a);
- EXPECT_EQ(c.Element<AInt>(2), 3_a);
- EXPECT_EQ(c.ElementCount(), 3u);
-}
-
-TEST_F(ConstantTest, Element_vec3_i32) {
- Constant c(create<Vector>(create<I32>(), 3u), {1_a, 2_a, 3_a});
- EXPECT_EQ(c.Element<i32>(0), 1_i);
- EXPECT_EQ(c.Element<i32>(1), 2_i);
- EXPECT_EQ(c.Element<i32>(2), 3_i);
- EXPECT_EQ(c.ElementCount(), 3u);
-}
-
-TEST_F(ConstantTest, Element_vec3_u32) {
- Constant c(create<Vector>(create<U32>(), 3u), {1_a, 2_a, 3_a});
- EXPECT_EQ(c.Element<u32>(0), 1_u);
- EXPECT_EQ(c.Element<u32>(1), 2_u);
- EXPECT_EQ(c.Element<u32>(2), 3_u);
- EXPECT_EQ(c.ElementCount(), 3u);
-}
-
-TEST_F(ConstantTest, Element_vec3_bool) {
- Constant c(create<Vector>(create<Bool>(), 2u), {true, false});
- EXPECT_EQ(c.Element<bool>(0), true);
- EXPECT_EQ(c.Element<bool>(1), false);
- EXPECT_EQ(c.ElementCount(), 2u);
-}
-
-TEST_F(ConstantTest, Element_vec3_af) {
- Constant c(create<Vector>(create<AbstractFloat>(), 3u), {1.0_a, 2.0_a, 3.0_a});
- EXPECT_EQ(c.Element<AFloat>(0), 1.0_a);
- EXPECT_EQ(c.Element<AFloat>(1), 2.0_a);
- EXPECT_EQ(c.Element<AFloat>(2), 3.0_a);
- EXPECT_EQ(c.ElementCount(), 3u);
-}
-
-TEST_F(ConstantTest, Element_vec3_f32) {
- Constant c(create<Vector>(create<F32>(), 3u), {1.0_a, 2.0_a, 3.0_a});
- EXPECT_EQ(c.Element<f32>(0), 1.0_f);
- EXPECT_EQ(c.Element<f32>(1), 2.0_f);
- EXPECT_EQ(c.Element<f32>(2), 3.0_f);
- EXPECT_EQ(c.ElementCount(), 3u);
-}
-
-TEST_F(ConstantTest, Element_vec3_f16) {
- Constant c(create<Vector>(create<F16>(), 3u), {1.0_a, 2.0_a, 3.0_a});
- EXPECT_EQ(c.Element<f16>(0), 1.0_h);
- EXPECT_EQ(c.Element<f16>(1), 2.0_h);
- EXPECT_EQ(c.Element<f16>(2), 3.0_h);
- EXPECT_EQ(c.ElementCount(), 3u);
-}
-
-TEST_F(ConstantTest, Element_mat2x3_af) {
- Constant c(create<Matrix>(create<Vector>(create<AbstractFloat>(), 3u), 2u),
- {1.0_a, 2.0_a, 3.0_a, 4.0_a, 5.0_a, 6.0_a});
- EXPECT_EQ(c.Element<AFloat>(0), 1.0_a);
- EXPECT_EQ(c.Element<AFloat>(1), 2.0_a);
- EXPECT_EQ(c.Element<AFloat>(2), 3.0_a);
- EXPECT_EQ(c.Element<AFloat>(3), 4.0_a);
- EXPECT_EQ(c.Element<AFloat>(4), 5.0_a);
- EXPECT_EQ(c.Element<AFloat>(5), 6.0_a);
- EXPECT_EQ(c.ElementCount(), 6u);
-}
-
-TEST_F(ConstantTest, Element_mat2x3_f32) {
- Constant c(create<Matrix>(create<Vector>(create<F32>(), 3u), 2u),
- {1.0_a, 2.0_a, 3.0_a, 4.0_a, 5.0_a, 6.0_a});
- EXPECT_EQ(c.Element<f32>(0), 1.0_f);
- EXPECT_EQ(c.Element<f32>(1), 2.0_f);
- EXPECT_EQ(c.Element<f32>(2), 3.0_f);
- EXPECT_EQ(c.Element<f32>(3), 4.0_f);
- EXPECT_EQ(c.Element<f32>(4), 5.0_f);
- EXPECT_EQ(c.Element<f32>(5), 6.0_f);
- EXPECT_EQ(c.ElementCount(), 6u);
-}
-
-TEST_F(ConstantTest, Element_mat2x3_f16) {
- Constant c(create<Matrix>(create<Vector>(create<F16>(), 3u), 2u),
- {1.0_a, 2.0_a, 3.0_a, 4.0_a, 5.0_a, 6.0_a});
- EXPECT_EQ(c.Element<f16>(0), 1.0_h);
- EXPECT_EQ(c.Element<f16>(1), 2.0_h);
- EXPECT_EQ(c.Element<f16>(2), 3.0_h);
- EXPECT_EQ(c.Element<f16>(3), 4.0_h);
- EXPECT_EQ(c.Element<f16>(4), 5.0_h);
- EXPECT_EQ(c.Element<f16>(5), 6.0_h);
- EXPECT_EQ(c.ElementCount(), 6u);
-}
-
-TEST_F(ConstantTest, AnyZero) {
- auto* vec3_ai = create<Vector>(create<AbstractInt>(), 3u);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 3_a}).AnyZero(), false);
- EXPECT_EQ(Constant(vec3_ai, {0_a, 2_a, 3_a}).AnyZero(), true);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 0_a, 3_a}).AnyZero(), true);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 0_a}).AnyZero(), true);
- EXPECT_EQ(Constant(vec3_ai, {0_a, 0_a, 0_a}).AnyZero(), true);
-
- auto* vec3_af = create<Vector>(create<AbstractFloat>(), 3u);
- EXPECT_EQ(Constant(vec3_af, {1._a, 2._a, 3._a}).AnyZero(), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, 2._a, 3._a}).AnyZero(), true);
- EXPECT_EQ(Constant(vec3_af, {1._a, 0._a, 3._a}).AnyZero(), true);
- EXPECT_EQ(Constant(vec3_af, {1._a, 2._a, 0._a}).AnyZero(), true);
- EXPECT_EQ(Constant(vec3_af, {0._a, 0._a, 0._a}).AnyZero(), true);
-
- EXPECT_EQ(Constant(vec3_af, {1._a, -2._a, 3._a}).AnyZero(), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, -2._a, 3._a}).AnyZero(), true);
- EXPECT_EQ(Constant(vec3_af, {1._a, -0._a, 3._a}).AnyZero(), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, -2._a, 0._a}).AnyZero(), true);
- EXPECT_EQ(Constant(vec3_af, {0._a, -0._a, 0._a}).AnyZero(), true);
- EXPECT_EQ(Constant(vec3_af, {-0._a, -0._a, -0._a}).AnyZero(), false);
-}
-
-TEST_F(ConstantTest, AllZero) {
- auto* vec3_ai = create<Vector>(create<AbstractInt>(), 3u);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 3_a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_ai, {0_a, 2_a, 3_a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 0_a, 3_a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 0_a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_ai, {0_a, 0_a, 0_a}).AllZero(), true);
-
- auto* vec3_af = create<Vector>(create<AbstractFloat>(), 3u);
- EXPECT_EQ(Constant(vec3_af, {1._a, 2._a, 3._a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, 2._a, 3._a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, 0._a, 3._a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, 2._a, 0._a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, 0._a, 0._a}).AllZero(), true);
-
- EXPECT_EQ(Constant(vec3_af, {1._a, -2._a, 3._a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, -2._a, 3._a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, -0._a, 3._a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, -2._a, 0._a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, -0._a, 0._a}).AllZero(), false);
- EXPECT_EQ(Constant(vec3_af, {-0._a, -0._a, -0._a}).AllZero(), false);
-}
-
-TEST_F(ConstantTest, AllEqual) {
- auto* vec3_ai = create<Vector>(create<AbstractInt>(), 3u);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 3_a}).AllEqual(), false);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 1_a, 3_a}).AllEqual(), false);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 3_a, 3_a}).AllEqual(), false);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 1_a, 1_a}).AllEqual(), true);
- EXPECT_EQ(Constant(vec3_ai, {2_a, 2_a, 2_a}).AllEqual(), true);
- EXPECT_EQ(Constant(vec3_ai, {3_a, 3_a, 3_a}).AllEqual(), true);
- EXPECT_EQ(Constant(vec3_ai, {0_a, 0_a, 0_a}).AllEqual(), true);
-
- auto* vec3_af = create<Vector>(create<AbstractFloat>(), 3u);
- EXPECT_EQ(Constant(vec3_af, {1._a, 2._a, 3._a}).AllEqual(), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, 1._a, 3._a}).AllEqual(), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, 3._a, 3._a}).AllEqual(), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, 1._a, 1._a}).AllEqual(), true);
- EXPECT_EQ(Constant(vec3_af, {2._a, 2._a, 2._a}).AllEqual(), true);
- EXPECT_EQ(Constant(vec3_af, {3._a, 3._a, 3._a}).AllEqual(), true);
- EXPECT_EQ(Constant(vec3_af, {0._a, 0._a, 0._a}).AllEqual(), true);
- EXPECT_EQ(Constant(vec3_af, {0._a, -0._a, 0._a}).AllEqual(), false);
-}
-
-TEST_F(ConstantTest, AllEqualRange) {
- auto* vec3_ai = create<Vector>(create<AbstractInt>(), 3u);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 3_a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 1_a, 3_a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 3_a, 3_a}).AllEqual(1, 3), true);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 1_a, 1_a}).AllEqual(1, 3), true);
- EXPECT_EQ(Constant(vec3_ai, {2_a, 2_a, 2_a}).AllEqual(1, 3), true);
- EXPECT_EQ(Constant(vec3_ai, {2_a, 2_a, 3_a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_ai, {1_a, 0_a, 0_a}).AllEqual(1, 3), true);
- EXPECT_EQ(Constant(vec3_ai, {0_a, 1_a, 0_a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_ai, {0_a, 0_a, 1_a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_ai, {0_a, 0_a, 0_a}).AllEqual(1, 3), true);
-
- auto* vec3_af = create<Vector>(create<AbstractFloat>(), 3u);
- EXPECT_EQ(Constant(vec3_af, {1._a, 2._a, 3._a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, 1._a, 3._a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, 3._a, 3._a}).AllEqual(1, 3), true);
- EXPECT_EQ(Constant(vec3_af, {1._a, 1._a, 1._a}).AllEqual(1, 3), true);
- EXPECT_EQ(Constant(vec3_af, {2._a, 2._a, 2._a}).AllEqual(1, 3), true);
- EXPECT_EQ(Constant(vec3_af, {2._a, 2._a, 3._a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_af, {1._a, 0._a, 0._a}).AllEqual(1, 3), true);
- EXPECT_EQ(Constant(vec3_af, {0._a, 1._a, 0._a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, 0._a, 1._a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, 0._a, 0._a}).AllEqual(1, 3), true);
- EXPECT_EQ(Constant(vec3_af, {1._a, -0._a, 0._a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, -1._a, 0._a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, -0._a, 1._a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, -0._a, 0._a}).AllEqual(1, 3), false);
- EXPECT_EQ(Constant(vec3_af, {0._a, -0._a, -0._a}).AllEqual(1, 3), true);
- EXPECT_EQ(Constant(vec3_af, {-0._a, -0._a, -0._a}).AllEqual(1, 3), true);
-}
-
-} // namespace
-} // namespace tint::sem
diff --git a/src/tint/sem/expression.cc b/src/tint/sem/expression.cc
index 57ec68b..4415db5 100644
--- a/src/tint/sem/expression.cc
+++ b/src/tint/sem/expression.cc
@@ -25,7 +25,7 @@
Expression::Expression(const ast::Expression* declaration,
const sem::Type* type,
const Statement* statement,
- Constant constant,
+ const Constant* constant,
bool has_side_effects,
const Variable* source_var /* = nullptr */)
: declaration_(declaration),
diff --git a/src/tint/sem/expression.h b/src/tint/sem/expression.h
index a783851..05e5dac 100644
--- a/src/tint/sem/expression.h
+++ b/src/tint/sem/expression.h
@@ -41,7 +41,7 @@
Expression(const ast::Expression* declaration,
const sem::Type* type,
const Statement* statement,
- Constant constant,
+ const Constant* constant,
bool has_side_effects,
const Variable* source_var = nullptr);
@@ -58,7 +58,7 @@
const Statement* Stmt() const { return statement_; }
/// @return the constant value of this expression
- const Constant& ConstantValue() const { return constant_; }
+ const Constant* ConstantValue() const { return constant_; }
/// Returns the variable or parameter that this expression derives from.
/// For reference and pointer expressions, this will either be the originating
@@ -88,7 +88,7 @@
private:
const sem::Type* const type_;
const Statement* const statement_;
- const Constant constant_;
+ const Constant* const constant_;
sem::Behaviors behaviors_{sem::Behavior::kNext};
const bool has_side_effects_;
};
diff --git a/src/tint/sem/expression_test.cc b/src/tint/sem/expression_test.cc
index fc1adeb..cc4bf0e 100644
--- a/src/tint/sem/expression_test.cc
+++ b/src/tint/sem/expression_test.cc
@@ -23,13 +23,30 @@
namespace tint::sem {
namespace {
+class MockConstant : public sem::Constant {
+ public:
+ explicit MockConstant(const sem::Type* ty) : type(ty) {}
+ ~MockConstant() override {}
+ const sem::Type* Type() const override { return type; }
+ std::variant<std::monostate, AInt, AFloat> Value() const override { return {}; }
+ const Constant* Index(size_t) const override { return {}; }
+ bool AllZero() const override { return {}; }
+ bool AnyZero() const override { return {}; }
+ bool AllEqual() const override { return {}; }
+ size_t Hash() const override { return 0; }
+
+ private:
+ const sem::Type* type;
+};
+
using ExpressionTest = TestHelper;
TEST_F(ExpressionTest, UnwrapMaterialize) {
+ MockConstant c(create<I32>());
auto* a = create<Expression>(/* declaration */ nullptr, create<I32>(), /* statement */ nullptr,
- Constant{},
+ /* constant_value */ nullptr,
/* has_side_effects */ false, /* source_var */ nullptr);
- auto* b = create<Materialize>(a, /* statement */ nullptr, Constant{create<I32>(), {1_a}});
+ auto* b = create<Materialize>(a, /* statement */ nullptr, &c);
EXPECT_EQ(a, a->UnwrapMaterialize());
EXPECT_EQ(a, b->UnwrapMaterialize());
diff --git a/src/tint/sem/index_accessor_expression.cc b/src/tint/sem/index_accessor_expression.cc
new file mode 100644
index 0000000..cd74201
--- /dev/null
+++ b/src/tint/sem/index_accessor_expression.cc
@@ -0,0 +1,39 @@
+// Copyright 2021 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/sem/index_accessor_expression.h"
+
+#include "src/tint/ast/index_accessor_expression.h"
+
+#include <utility>
+
+TINT_INSTANTIATE_TYPEINFO(tint::sem::IndexAccessorExpression);
+
+namespace tint::sem {
+
+IndexAccessorExpression::IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
+ const sem::Type* type,
+ const Expression* object,
+ const Expression* index,
+ const Statement* statement,
+ const Constant* constant,
+ bool has_side_effects,
+ const Variable* source_var /* = nullptr */)
+ : Base(declaration, type, statement, constant, has_side_effects, source_var),
+ object_(object),
+ index_(index) {}
+
+IndexAccessorExpression::~IndexAccessorExpression() = default;
+
+} // namespace tint::sem
diff --git a/src/tint/sem/index_accessor_expression.h b/src/tint/sem/index_accessor_expression.h
new file mode 100644
index 0000000..233b0fa
--- /dev/null
+++ b/src/tint/sem/index_accessor_expression.h
@@ -0,0 +1,66 @@
+// 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_SEM_INDEX_ACCESSOR_EXPRESSION_H_
+#define SRC_TINT_SEM_INDEX_ACCESSOR_EXPRESSION_H_
+
+#include <vector>
+
+#include "src/tint/sem/expression.h"
+
+// Forward declarations
+namespace tint::ast {
+class IndexAccessorExpression;
+} // namespace tint::ast
+
+namespace tint::sem {
+
+/// IndexAccessorExpression holds the semantic information for a ast::IndexAccessorExpression node.
+class IndexAccessorExpression final : public Castable<IndexAccessorExpression, Expression> {
+ public:
+ /// Constructor
+ /// @param declaration the AST node
+ /// @param type the resolved type of the expression
+ /// @param object the object expression that is being indexed
+ /// @param index the index expression
+ /// @param statement the statement that owns this expression
+ /// @param constant the constant value of the expression. May be invalid
+ /// @param has_side_effects whether this expression may have side effects
+ /// @param source_var the (optional) source variable for this expression
+ IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
+ const sem::Type* type,
+ const Expression* object,
+ const Expression* index,
+ const Statement* statement,
+ const Constant* constant,
+ bool has_side_effects,
+ const Variable* source_var = nullptr);
+
+ /// Destructor
+ ~IndexAccessorExpression() override;
+
+ /// @returns the object expression that is being indexed
+ Expression const* Object() const { return object_; }
+
+ /// @returns the index expression
+ Expression const* Index() const { return index_; }
+
+ private:
+ Expression const* const object_;
+ Expression const* const index_;
+};
+
+} // namespace tint::sem
+
+#endif // SRC_TINT_SEM_INDEX_ACCESSOR_EXPRESSION_H_
diff --git a/src/tint/sem/materialize.cc b/src/tint/sem/materialize.cc
index 76dd9d4..739b0ce 100644
--- a/src/tint/sem/materialize.cc
+++ b/src/tint/sem/materialize.cc
@@ -17,19 +17,16 @@
TINT_INSTANTIATE_TYPEINFO(tint::sem::Materialize);
namespace tint::sem {
-
-Materialize::Materialize(const Expression* expr, const Statement* statement, Constant constant)
+Materialize::Materialize(const Expression* expr,
+ const Statement* statement,
+ const Constant* constant)
: Base(/* declaration */ expr->Declaration(),
- /* type */ constant.Type(),
+ /* type */ constant->Type(),
/* statement */ statement,
/* constant */ constant,
/* has_side_effects */ false,
/* source_var */ expr->SourceVariable()),
- expr_(expr) {
- // Materialize nodes only wrap compile-time expressions, and so the Materialize expression must
- // have a constant value.
- TINT_ASSERT(Semantic, constant.IsValid());
-}
+ expr_(expr) {}
Materialize::~Materialize() = default;
diff --git a/src/tint/sem/materialize.h b/src/tint/sem/materialize.h
index a7c0e3a..0cbac29 100644
--- a/src/tint/sem/materialize.h
+++ b/src/tint/sem/materialize.h
@@ -31,7 +31,7 @@
/// @param expr the inner expression, being materialized
/// @param statement the statement that owns this expression
/// @param constant the constant value of this expression
- Materialize(const Expression* expr, const Statement* statement, Constant constant);
+ Materialize(const Expression* expr, const Statement* statement, const Constant* constant);
/// Destructor
~Materialize() override;
diff --git a/src/tint/sem/member_accessor_expression.cc b/src/tint/sem/member_accessor_expression.cc
index 9dcca76..f9929c7 100644
--- a/src/tint/sem/member_accessor_expression.cc
+++ b/src/tint/sem/member_accessor_expression.cc
@@ -26,29 +26,32 @@
MemberAccessorExpression::MemberAccessorExpression(const ast::MemberAccessorExpression* declaration,
const sem::Type* type,
const Statement* statement,
+ const Expression* object,
bool has_side_effects,
const Variable* source_var /* = nullptr */)
- : Base(declaration, type, statement, Constant{}, has_side_effects, source_var) {}
+ : Base(declaration, type, statement, nullptr, has_side_effects, source_var), object_(object) {}
MemberAccessorExpression::~MemberAccessorExpression() = default;
StructMemberAccess::StructMemberAccess(const ast::MemberAccessorExpression* declaration,
const sem::Type* type,
const Statement* statement,
+ const Expression* object,
const StructMember* member,
bool has_side_effects,
const Variable* source_var /* = nullptr */)
- : Base(declaration, type, statement, has_side_effects, source_var), member_(member) {}
+ : Base(declaration, type, statement, object, has_side_effects, source_var), member_(member) {}
StructMemberAccess::~StructMemberAccess() = default;
Swizzle::Swizzle(const ast::MemberAccessorExpression* declaration,
const sem::Type* type,
const Statement* statement,
+ const Expression* object,
std::vector<uint32_t> indices,
bool has_side_effects,
const Variable* source_var /* = nullptr */)
- : Base(declaration, type, statement, has_side_effects, source_var),
+ : Base(declaration, type, statement, object, has_side_effects, source_var),
indices_(std::move(indices)) {}
Swizzle::~Swizzle() = default;
diff --git a/src/tint/sem/member_accessor_expression.h b/src/tint/sem/member_accessor_expression.h
index 0233541..3d60816 100644
--- a/src/tint/sem/member_accessor_expression.h
+++ b/src/tint/sem/member_accessor_expression.h
@@ -38,16 +38,24 @@
/// @param declaration the AST node
/// @param type the resolved type of the expression
/// @param statement the statement that owns this expression
+ /// @param object the object that holds the member being accessed
/// @param has_side_effects whether this expression may have side effects
/// @param source_var the (optional) source variable for this expression
MemberAccessorExpression(const ast::MemberAccessorExpression* declaration,
const sem::Type* type,
const Statement* statement,
+ const Expression* object,
bool has_side_effects,
const Variable* source_var = nullptr);
/// Destructor
~MemberAccessorExpression() override;
+
+ /// @returns the object that holds the member being accessed
+ const Expression* Object() const { return object_; }
+
+ private:
+ Expression const* const object_;
};
/// StructMemberAccess holds the semantic information for a
@@ -59,12 +67,14 @@
/// @param declaration the AST node
/// @param type the resolved type of the expression
/// @param statement the statement that owns this expression
+ /// @param object the object that holds the member being accessed
/// @param member the structure member
/// @param has_side_effects whether this expression may have side effects
/// @param source_var the (optional) source variable for this expression
StructMemberAccess(const ast::MemberAccessorExpression* declaration,
const sem::Type* type,
const Statement* statement,
+ const Expression* object,
const StructMember* member,
bool has_side_effects,
const Variable* source_var = nullptr);
@@ -87,12 +97,14 @@
/// @param declaration the AST node
/// @param type the resolved type of the expression
/// @param statement the statement that owns this expression
+ /// @param object the object that holds the member being accessed
/// @param indices the swizzle indices
/// @param has_side_effects whether this expression may have side effects
/// @param source_var the (optional) source variable for this expression
Swizzle(const ast::MemberAccessorExpression* declaration,
const sem::Type* type,
const Statement* statement,
+ const Expression* object,
std::vector<uint32_t> indices,
bool has_side_effects,
const Variable* source_var = nullptr);
diff --git a/src/tint/sem/struct.h b/src/tint/sem/struct.h
index fe9169d..e026b11 100644
--- a/src/tint/sem/struct.h
+++ b/src/tint/sem/struct.h
@@ -194,9 +194,16 @@
/// @returns the AST declaration node
const ast::StructMember* Declaration() const { return declaration_; }
- /// @returns the name of the structure
+ /// @returns the name of the structure member
Symbol Name() const { return name_; }
+ /// Sets the owning structure to `s`
+ /// @param s the new structure owner
+ void SetStruct(const sem::Struct* s) { struct_ = s; }
+
+ /// @returns the structure that owns this member
+ const sem::Struct* Struct() const { return struct_; }
+
/// @returns the type of the member
sem::Type* Type() const { return type_; }
@@ -215,6 +222,7 @@
private:
const ast::StructMember* const declaration_;
const Symbol name_;
+ const sem::Struct* struct_;
sem::Type* const type_;
const uint32_t index_;
const uint32_t offset_;
diff --git a/src/tint/sem/type.cc b/src/tint/sem/type.cc
index 40666e3..9d4c469 100644
--- a/src/tint/sem/type.cc
+++ b/src/tint/sem/type.cc
@@ -220,18 +220,38 @@
},
[&](const Matrix* m) {
if (count) {
- *count = m->columns() * m->rows();
+ *count = m->columns();
}
- return m->type();
+ return m->ColumnType();
},
[&](const Array* a) {
if (count) {
*count = a->Count();
}
return a->ElemType();
+ },
+ [&](Default) {
+ if (count) {
+ *count = 0;
+ }
+ return nullptr;
});
}
+const Type* Type::DeepestElementOf(const Type* ty, uint32_t* count /* = nullptr */) {
+ auto el_ty = ElementOf(ty, count);
+ while (el_ty && ty != el_ty) {
+ ty = el_ty;
+
+ uint32_t n = 0;
+ el_ty = ElementOf(ty, &n);
+ if (count) {
+ *count *= n;
+ }
+ }
+ return el_ty;
+}
+
const sem::Type* Type::Common(Type const* const* types, size_t count) {
if (count == 0) {
return nullptr;
diff --git a/src/tint/sem/type.h b/src/tint/sem/type.h
index 9987637..25f3a43 100644
--- a/src/tint/sem/type.h
+++ b/src/tint/sem/type.h
@@ -130,11 +130,26 @@
static uint32_t ConversionRank(const Type* from, const Type* to);
/// @param ty the type to obtain the element type from
- /// @param count if not null, then this is assigned the number of elements in the type
- /// @returns `ty` if `ty` is an abstract or scalar, the element type if ty is a vector, matrix
- /// or array, otherwise nullptr.
+ /// @param count if not null, then this is assigned the number of child elements in the type.
+ /// For example, the count of an `array<vec3<f32>, 5>` type would be 5.
+ /// @returns
+ /// * `ty` if `ty` is an abstract or scalar
+ /// * the element type if `ty` is a vector or array
+ /// * the column type if `ty` is a matrix
+ /// * `nullptr` if `ty` is none of the above
static const Type* ElementOf(const Type* ty, uint32_t* count = nullptr);
+ /// @param ty the type to obtain the deepest element type from
+ /// @param count if not null, then this is assigned the full number of most deeply nested
+ /// elements in the type. For example, the count of an `array<vec3<f32>, 5>` type would be 15.
+ /// @returns
+ /// * `ty` if `ty` is an abstract or scalar
+ /// * the element type if `ty` is a vector
+ /// * the matrix element type if `ty` is a matrix
+ /// * the deepest element type if `ty` is an array
+ /// * `nullptr` if `ty` is none of the above
+ static const Type* DeepestElementOf(const Type* ty, uint32_t* count = nullptr);
+
/// @param types a pointer to a list of `const Type*`.
/// @param count the number of types in `types`.
/// @returns the lowest-ranking type that all types in `types` can be implicitly converted to,
diff --git a/src/tint/sem/type_mappings.h b/src/tint/sem/type_mappings.h
index 9041bdb..7dc0ade 100644
--- a/src/tint/sem/type_mappings.h
+++ b/src/tint/sem/type_mappings.h
@@ -25,6 +25,7 @@
class ForLoopStatement;
class Function;
class IfStatement;
+class IndexAccessorExpression;
class MemberAccessorExpression;
class Node;
class Override;
@@ -44,6 +45,7 @@
class ForLoopStatement;
class Function;
class IfStatement;
+class IndexAccessorExpression;
class MemberAccessorExpression;
class Node;
class GlobalVariable;
@@ -69,6 +71,7 @@
ForLoopStatement* operator()(ast::ForLoopStatement*);
Function* operator()(ast::Function*);
IfStatement* operator()(ast::IfStatement*);
+ IndexAccessorExpression* operator()(ast::IndexAccessorExpression*);
MemberAccessorExpression* operator()(ast::MemberAccessorExpression*);
Node* operator()(ast::Node*);
GlobalVariable* operator()(ast::Override*);
diff --git a/src/tint/sem/type_test.cc b/src/tint/sem/type_test.cc
index c11efea..8458880 100644
--- a/src/tint/sem/type_test.cc
+++ b/src/tint/sem/type_test.cc
@@ -104,6 +104,20 @@
auto* mat2x4_f32 = create<Matrix>(vec4_f32, 2u);
auto* mat4x2_f32 = create<Matrix>(vec2_f32, 4u);
auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
+ auto* str = create<Struct>(nullptr, Sym("s"),
+ StructMemberList{
+ create<StructMember>(
+ /* declaration */ nullptr,
+ /* name */ Sym("x"),
+ /* type */ f16,
+ /* index */ 0u,
+ /* offset */ 0u,
+ /* align */ 4u,
+ /* size */ 4u),
+ },
+ /* align*/ 4u,
+ /* size*/ 4u,
+ /* size_no_padding*/ 4u);
auto* arr_i32 = create<Array>(
/* element */ i32,
/* count */ 5u,
@@ -111,6 +125,27 @@
/* size */ 5u * 4u,
/* stride */ 5u * 4u,
/* implicit_stride */ 5u * 4u);
+ auto* arr_vec3_i32 = create<Array>(
+ /* element */ vec3_i32,
+ /* count */ 5u,
+ /* align */ 16u,
+ /* size */ 5u * 16u,
+ /* stride */ 5u * 16u,
+ /* implicit_stride */ 5u * 16u);
+ auto* arr_mat4x3_f16 = create<Array>(
+ /* element */ mat4x3_f16,
+ /* count */ 5u,
+ /* align */ 64u,
+ /* size */ 5u * 64u,
+ /* stride */ 5u * 64u,
+ /* implicit_stride */ 5u * 64u);
+ auto* arr_str = create<Array>(
+ /* element */ str,
+ /* count */ 5u,
+ /* align */ 4u,
+ /* size */ 5u * 4u,
+ /* stride */ 5u * 4u,
+ /* implicit_stride */ 5u * 4u);
// No count
EXPECT_TYPE(Type::ElementOf(f32), f32);
@@ -122,51 +157,196 @@
EXPECT_TYPE(Type::ElementOf(vec4_f32), f32);
EXPECT_TYPE(Type::ElementOf(vec3_u32), u32);
EXPECT_TYPE(Type::ElementOf(vec3_i32), i32);
- EXPECT_TYPE(Type::ElementOf(mat2x4_f32), f32);
- EXPECT_TYPE(Type::ElementOf(mat4x2_f32), f32);
- EXPECT_TYPE(Type::ElementOf(mat4x3_f16), f16);
+ EXPECT_TYPE(Type::ElementOf(mat2x4_f32), vec4_f32);
+ EXPECT_TYPE(Type::ElementOf(mat4x2_f32), vec2_f32);
+ EXPECT_TYPE(Type::ElementOf(mat4x3_f16), vec3_f16);
+ EXPECT_TYPE(Type::ElementOf(str), nullptr);
EXPECT_TYPE(Type::ElementOf(arr_i32), i32);
+ EXPECT_TYPE(Type::ElementOf(arr_vec3_i32), vec3_i32);
+ EXPECT_TYPE(Type::ElementOf(arr_mat4x3_f16), mat4x3_f16);
+ EXPECT_TYPE(Type::ElementOf(arr_str), str);
// With count
- uint32_t count = 0;
+ uint32_t count = 42;
EXPECT_TYPE(Type::ElementOf(f32, &count), f32);
EXPECT_EQ(count, 1u);
- count = 0;
+ count = 42;
EXPECT_TYPE(Type::ElementOf(f16, &count), f16);
EXPECT_EQ(count, 1u);
- count = 0;
+ count = 42;
EXPECT_TYPE(Type::ElementOf(i32, &count), i32);
EXPECT_EQ(count, 1u);
- count = 0;
+ count = 42;
EXPECT_TYPE(Type::ElementOf(u32, &count), u32);
EXPECT_EQ(count, 1u);
- count = 0;
+ count = 42;
EXPECT_TYPE(Type::ElementOf(vec2_f32, &count), f32);
EXPECT_EQ(count, 2u);
- count = 0;
+ count = 42;
EXPECT_TYPE(Type::ElementOf(vec3_f16, &count), f16);
EXPECT_EQ(count, 3u);
- count = 0;
+ count = 42;
EXPECT_TYPE(Type::ElementOf(vec4_f32, &count), f32);
EXPECT_EQ(count, 4u);
- count = 0;
+ count = 42;
EXPECT_TYPE(Type::ElementOf(vec3_u32, &count), u32);
EXPECT_EQ(count, 3u);
- count = 0;
+ count = 42;
EXPECT_TYPE(Type::ElementOf(vec3_i32, &count), i32);
EXPECT_EQ(count, 3u);
- count = 0;
- EXPECT_TYPE(Type::ElementOf(mat2x4_f32, &count), f32);
- EXPECT_EQ(count, 8u);
- count = 0;
- EXPECT_TYPE(Type::ElementOf(mat4x2_f32, &count), f32);
- EXPECT_EQ(count, 8u);
- count = 0;
- EXPECT_TYPE(Type::ElementOf(mat4x3_f16, &count), f16);
- EXPECT_EQ(count, 12u);
- count = 0;
+ count = 42;
+ EXPECT_TYPE(Type::ElementOf(mat2x4_f32, &count), vec4_f32);
+ EXPECT_EQ(count, 2u);
+ count = 42;
+ EXPECT_TYPE(Type::ElementOf(mat4x2_f32, &count), vec2_f32);
+ EXPECT_EQ(count, 4u);
+ count = 42;
+ EXPECT_TYPE(Type::ElementOf(mat4x3_f16, &count), vec3_f16);
+ EXPECT_EQ(count, 4u);
+ count = 42;
+ EXPECT_TYPE(Type::ElementOf(str, &count), nullptr);
+ EXPECT_EQ(count, 0u);
+ count = 42;
EXPECT_TYPE(Type::ElementOf(arr_i32, &count), i32);
EXPECT_EQ(count, 5u);
+ count = 42;
+ EXPECT_TYPE(Type::ElementOf(arr_vec3_i32, &count), vec3_i32);
+ EXPECT_EQ(count, 5u);
+ count = 42;
+ EXPECT_TYPE(Type::ElementOf(arr_mat4x3_f16, &count), mat4x3_f16);
+ EXPECT_EQ(count, 5u);
+ count = 42;
+ EXPECT_TYPE(Type::ElementOf(arr_str, &count), str);
+ EXPECT_EQ(count, 5u);
+}
+
+TEST_F(TypeTest, DeepestElementOf) {
+ auto* f32 = create<F32>();
+ auto* f16 = create<F16>();
+ auto* i32 = create<I32>();
+ auto* u32 = create<U32>();
+ auto* vec2_f32 = create<Vector>(f32, 2u);
+ auto* vec3_f16 = create<Vector>(f16, 3u);
+ auto* vec4_f32 = create<Vector>(f32, 4u);
+ auto* vec3_u32 = create<Vector>(u32, 3u);
+ auto* vec3_i32 = create<Vector>(i32, 3u);
+ auto* mat2x4_f32 = create<Matrix>(vec4_f32, 2u);
+ auto* mat4x2_f32 = create<Matrix>(vec2_f32, 4u);
+ auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
+ auto* str = create<Struct>(nullptr, Sym("s"),
+ StructMemberList{
+ create<StructMember>(
+ /* declaration */ nullptr,
+ /* name */ Sym("x"),
+ /* type */ f16,
+ /* index */ 0u,
+ /* offset */ 0u,
+ /* align */ 4u,
+ /* size */ 4u),
+ },
+ /* align*/ 4u,
+ /* size*/ 4u,
+ /* size_no_padding*/ 4u);
+ auto* arr_i32 = create<Array>(
+ /* element */ i32,
+ /* count */ 5u,
+ /* align */ 4u,
+ /* size */ 5u * 4u,
+ /* stride */ 5u * 4u,
+ /* implicit_stride */ 5u * 4u);
+ auto* arr_vec3_i32 = create<Array>(
+ /* element */ vec3_i32,
+ /* count */ 5u,
+ /* align */ 16u,
+ /* size */ 5u * 16u,
+ /* stride */ 5u * 16u,
+ /* implicit_stride */ 5u * 16u);
+ auto* arr_mat4x3_f16 = create<Array>(
+ /* element */ mat4x3_f16,
+ /* count */ 5u,
+ /* align */ 64u,
+ /* size */ 5u * 64u,
+ /* stride */ 5u * 64u,
+ /* implicit_stride */ 5u * 64u);
+ auto* arr_str = create<Array>(
+ /* element */ str,
+ /* count */ 5u,
+ /* align */ 4u,
+ /* size */ 5u * 4u,
+ /* stride */ 5u * 4u,
+ /* implicit_stride */ 5u * 4u);
+
+ // No count
+ EXPECT_TYPE(Type::DeepestElementOf(f32), f32);
+ EXPECT_TYPE(Type::DeepestElementOf(f16), f16);
+ EXPECT_TYPE(Type::DeepestElementOf(i32), i32);
+ EXPECT_TYPE(Type::DeepestElementOf(u32), u32);
+ EXPECT_TYPE(Type::DeepestElementOf(vec2_f32), f32);
+ EXPECT_TYPE(Type::DeepestElementOf(vec3_f16), f16);
+ EXPECT_TYPE(Type::DeepestElementOf(vec4_f32), f32);
+ EXPECT_TYPE(Type::DeepestElementOf(vec3_u32), u32);
+ EXPECT_TYPE(Type::DeepestElementOf(vec3_i32), i32);
+ EXPECT_TYPE(Type::DeepestElementOf(mat2x4_f32), f32);
+ EXPECT_TYPE(Type::DeepestElementOf(mat4x2_f32), f32);
+ EXPECT_TYPE(Type::DeepestElementOf(mat4x3_f16), f16);
+ EXPECT_TYPE(Type::DeepestElementOf(str), nullptr);
+ EXPECT_TYPE(Type::DeepestElementOf(arr_i32), i32);
+ EXPECT_TYPE(Type::DeepestElementOf(arr_vec3_i32), i32);
+ EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_f16), f16);
+ EXPECT_TYPE(Type::DeepestElementOf(arr_str), nullptr);
+
+ // With count
+ uint32_t count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(f32, &count), f32);
+ EXPECT_EQ(count, 1u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(f16, &count), f16);
+ EXPECT_EQ(count, 1u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(i32, &count), i32);
+ EXPECT_EQ(count, 1u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(u32, &count), u32);
+ EXPECT_EQ(count, 1u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(vec2_f32, &count), f32);
+ EXPECT_EQ(count, 2u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(vec3_f16, &count), f16);
+ EXPECT_EQ(count, 3u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(vec4_f32, &count), f32);
+ EXPECT_EQ(count, 4u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(vec3_u32, &count), u32);
+ EXPECT_EQ(count, 3u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(vec3_i32, &count), i32);
+ EXPECT_EQ(count, 3u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(mat2x4_f32, &count), f32);
+ EXPECT_EQ(count, 8u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(mat4x2_f32, &count), f32);
+ EXPECT_EQ(count, 8u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(mat4x3_f16, &count), f16);
+ EXPECT_EQ(count, 12u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(str, &count), nullptr);
+ EXPECT_EQ(count, 0u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(arr_i32, &count), i32);
+ EXPECT_EQ(count, 5u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(arr_vec3_i32, &count), i32);
+ EXPECT_EQ(count, 15u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_f16, &count), f16);
+ EXPECT_EQ(count, 60u);
+ count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(arr_str, &count), nullptr);
+ EXPECT_EQ(count, 0u);
}
TEST_F(TypeTest, Common2) {
diff --git a/src/tint/sem/variable.cc b/src/tint/sem/variable.cc
index de5cfa4..3849807 100644
--- a/src/tint/sem/variable.cc
+++ b/src/tint/sem/variable.cc
@@ -17,7 +17,9 @@
#include <utility>
#include "src/tint/ast/identifier_expression.h"
+#include "src/tint/ast/parameter.h"
#include "src/tint/ast/variable.h"
+#include "src/tint/sem/pointer.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Variable);
TINT_INSTANTIATE_TYPEINFO(tint::sem::GlobalVariable);
@@ -31,7 +33,7 @@
const sem::Type* type,
ast::StorageClass storage_class,
ast::Access access,
- Constant constant_value)
+ const Constant* constant_value)
: declaration_(declaration),
type_(type),
storage_class_(storage_class),
@@ -45,9 +47,8 @@
ast::StorageClass storage_class,
ast::Access access,
const sem::Statement* statement,
- Constant constant_value)
- : Base(declaration, type, storage_class, access, std::move(constant_value)),
- statement_(statement) {}
+ const Constant* constant_value)
+ : Base(declaration, type, storage_class, access, constant_value), statement_(statement) {}
LocalVariable::~LocalVariable() = default;
@@ -55,9 +56,9 @@
const sem::Type* type,
ast::StorageClass storage_class,
ast::Access access,
- Constant constant_value,
+ const Constant* constant_value,
sem::BindingPoint binding_point)
- : Base(declaration, type, storage_class, access, std::move(constant_value)),
+ : Base(declaration, type, storage_class, access, constant_value),
binding_point_(binding_point) {}
GlobalVariable::~GlobalVariable() = default;
@@ -68,7 +69,7 @@
ast::StorageClass storage_class,
ast::Access access,
const ParameterUsage usage /* = ParameterUsage::kNone */)
- : Base(declaration, type, storage_class, access, Constant{}), index_(index), usage_(usage) {}
+ : Base(declaration, type, storage_class, access, nullptr), index_(index), usage_(usage) {}
Parameter::~Parameter() = default;
@@ -89,4 +90,6 @@
}
}
+VariableUser::~VariableUser() = default;
+
} // namespace tint::sem
diff --git a/src/tint/sem/variable.h b/src/tint/sem/variable.h
index b995233..28e8f97 100644
--- a/src/tint/sem/variable.h
+++ b/src/tint/sem/variable.h
@@ -27,6 +27,7 @@
// Forward declarations
namespace tint::ast {
class IdentifierExpression;
+class Parameter;
class Variable;
} // namespace tint::ast
namespace tint::sem {
@@ -51,7 +52,7 @@
const sem::Type* type,
ast::StorageClass storage_class,
ast::Access access,
- Constant constant_value);
+ const Constant* constant_value);
/// Destructor
~Variable() override;
@@ -69,7 +70,7 @@
ast::Access Access() const { return access_; }
/// @return the constant value of this expression
- const Constant& ConstantValue() const { return constant_value_; }
+ const Constant* ConstantValue() const { return constant_value_; }
/// @returns the variable constructor expression, or nullptr if the variable
/// does not have one.
@@ -90,7 +91,7 @@
const sem::Type* const type_;
const ast::StorageClass storage_class_;
const ast::Access access_;
- const Constant constant_value_;
+ const Constant* constant_value_;
const Expression* constructor_ = nullptr;
std::vector<const VariableUser*> users_;
};
@@ -110,7 +111,7 @@
ast::StorageClass storage_class,
ast::Access access,
const sem::Statement* statement,
- Constant constant_value);
+ const Constant* constant_value);
/// Destructor
~LocalVariable() override;
@@ -144,7 +145,7 @@
const sem::Type* type,
ast::StorageClass storage_class,
ast::Access access,
- Constant constant_value,
+ const Constant* constant_value,
sem::BindingPoint binding_point = {});
/// Destructor
@@ -225,6 +226,7 @@
VariableUser(const ast::IdentifierExpression* declaration,
Statement* statement,
sem::Variable* variable);
+ ~VariableUser() override;
/// @returns the variable that this expression refers to
const sem::Variable* Variable() const { return variable_; }
diff --git a/src/tint/tint.natvis b/src/tint/tint.natvis
index c1fd1f3..bce3ce5 100644
--- a/src/tint/tint.natvis
+++ b/src/tint/tint.natvis
@@ -101,11 +101,7 @@
<DisplayString>{*variable};</DisplayString>
</Type>
- <Type Name="tint::ast::UintLiteralExpression">
- <DisplayString>{value}</DisplayString>
- </Type>
-
- <Type Name="tint::ast::SintLiteralExpression">
+ <Type Name="tint::ast::IntLiteralExpression">
<DisplayString>{value}</DisplayString>
</Type>
diff --git a/src/tint/transform/array_length_from_uniform.cc b/src/tint/transform/array_length_from_uniform.cc
index 86c4534..81471ad 100644
--- a/src/tint/transform/array_length_from_uniform.cc
+++ b/src/tint/transform/array_length_from_uniform.cc
@@ -144,7 +144,7 @@
{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->Global(
+ buffer_size_ubo = ctx.dst->GlobalVar(
ctx.dst->Sym(), ctx.dst->ty.Of(buffer_size_struct), ast::StorageClass::kUniform,
ast::AttributeList{
ctx.dst->GroupAndBinding(cfg->ubo_binding.group, cfg->ubo_binding.binding)});
diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc
index 9bde1cc..b0f6297 100644
--- a/src/tint/transform/builtin_polyfill.cc
+++ b/src/tint/transform/builtin_polyfill.cc
@@ -44,6 +44,100 @@
/// The source clone context
const sem::Info& sem = ctx.src->Sem();
+ /// Builds the polyfill function for the `acosh` builtin
+ /// @param ty the parameter and return type for the function
+ /// @return the polyfill function name
+ Symbol acosh(const sem::Type* ty) {
+ auto name = b.Symbols().New("tint_acosh");
+ uint32_t width = WidthOf(ty);
+
+ auto V = [&](AFloat value) -> const ast::Expression* {
+ const ast::Expression* expr = b.Expr(value);
+ if (width == 1) {
+ return expr;
+ }
+ return b.Construct(T(ty), expr);
+ };
+
+ ast::StatementList body;
+ switch (polyfill.acosh) {
+ case Level::kFull:
+ // return log(x + sqrt(x*x - 1));
+ body.emplace_back(b.Return(
+ b.Call("log", b.Add("x", b.Call("sqrt", b.Sub(b.Mul("x", "x"), 1_a))))));
+ break;
+ case Level::kRangeCheck: {
+ // return select(acosh(x), 0, x < 1);
+ body.emplace_back(b.Return(
+ b.Call("select", b.Call("acosh", "x"), V(0.0_a), b.LessThan("x", V(1.0_a)))));
+ break;
+ }
+ default:
+ TINT_ICE(Transform, b.Diagnostics())
+ << "unhandled polyfill level: " << static_cast<int>(polyfill.acosh);
+ return {};
+ }
+
+ b.Func(name, {b.Param("x", T(ty))}, T(ty), body);
+
+ return name;
+ }
+
+ /// Builds the polyfill function for the `asinh` builtin
+ /// @param ty the parameter and return type for the function
+ /// @return the polyfill function name
+ Symbol asinh(const sem::Type* ty) {
+ auto name = b.Symbols().New("tint_sinh");
+
+ ast::StatementList body;
+
+ // return log(x + sqrt(x*x + 1));
+ body.emplace_back(
+ b.Return(b.Call("log", b.Add("x", b.Call("sqrt", b.Add(b.Mul("x", "x"), 1_a))))));
+
+ b.Func(name, {b.Param("x", T(ty))}, T(ty), body);
+
+ return name;
+ }
+
+ /// Builds the polyfill function for the `atanh` builtin
+ /// @param ty the parameter and return type for the function
+ /// @return the polyfill function name
+ Symbol atanh(const sem::Type* ty) {
+ auto name = b.Symbols().New("tint_atanh");
+ uint32_t width = WidthOf(ty);
+
+ auto V = [&](AFloat value) -> const ast::Expression* {
+ const ast::Expression* expr = b.Expr(value);
+ if (width == 1) {
+ return expr;
+ }
+ return b.Construct(T(ty), expr);
+ };
+
+ ast::StatementList body;
+ switch (polyfill.atanh) {
+ case Level::kFull:
+ // return log((1+x) / (1-x)) * 0.5
+ body.emplace_back(
+ b.Return(b.Mul(b.Call("log", b.Div(b.Add(1_a, "x"), b.Sub(1_a, "x"))), 0.5_a)));
+ break;
+ case Level::kRangeCheck:
+ // return select(atanh(x), 0, x >= 1);
+ body.emplace_back(b.Return(b.Call("select", b.Call("atanh", "x"), V(0.0_a),
+ b.GreaterThanEqual("x", V(1.0_a)))));
+ break;
+ default:
+ TINT_ICE(Transform, b.Diagnostics())
+ << "unhandled polyfill level: " << static_cast<int>(polyfill.acosh);
+ return {};
+ }
+
+ b.Func(name, {b.Param("x", T(ty))}, T(ty), body);
+
+ return name;
+ }
+
/// Builds the polyfill function for the `countLeadingZeros` builtin
/// @param ty the parameter and return type for the function
/// @return the polyfill function name
@@ -440,6 +534,21 @@
if (auto* call = sem.Get<sem::Call>(node)) {
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
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::kCountLeadingZeros:
if (builtins.count_leading_zeros) {
return true;
@@ -496,6 +605,24 @@
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
Symbol polyfill;
switch (builtin->Type()) {
+ case sem::BuiltinType::kAcosh:
+ if (builtins.acosh != Level::kNone) {
+ polyfill = utils::GetOrCreate(
+ polyfills, builtin, [&] { return s.acosh(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::kCountLeadingZeros:
if (builtins.count_leading_zeros) {
polyfill = utils::GetOrCreate(polyfills, builtin, [&] {
diff --git a/src/tint/transform/builtin_polyfill.h b/src/tint/transform/builtin_polyfill.h
index 8453189..8df4197 100644
--- a/src/tint/transform/builtin_polyfill.h
+++ b/src/tint/transform/builtin_polyfill.h
@@ -33,12 +33,20 @@
kNone,
/// Clamp the parameters to the inner implementation.
kClampParameters,
+ /// Range check the input.
+ kRangeCheck,
/// Polyfill the entire function
kFull,
};
/// Specifies the builtins that should be polyfilled by the transform.
struct Builtins {
+ /// What level should `acosh` be polyfilled?
+ Level acosh = Level::kNone;
+ /// Should `asinh` be polyfilled?
+ bool asinh = false;
+ /// What level should `atanh` be polyfilled?
+ Level atanh = Level::kNone;
/// Should `countLeadingZeros()` be polyfilled?
bool count_leading_zeros = false;
/// Should `countTrailingZeros()` be polyfilled?
diff --git a/src/tint/transform/builtin_polyfill_test.cc b/src/tint/transform/builtin_polyfill_test.cc
index bc3dda8..1292b65 100644
--- a/src/tint/transform/builtin_polyfill_test.cc
+++ b/src/tint/transform/builtin_polyfill_test.cc
@@ -42,6 +42,292 @@
}
////////////////////////////////////////////////////////////////////////////////
+// acosh
+////////////////////////////////////////////////////////////////////////////////
+DataMap polyfillAcosh(Level level) {
+ BuiltinPolyfill::Builtins builtins;
+ builtins.acosh = level;
+ DataMap data;
+ data.Add<BuiltinPolyfill::Config>(builtins);
+ return data;
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunAcosh) {
+ auto* src = R"(
+fn f() {
+ acosh(1.0);
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src, polyfillAcosh(Level::kNone)));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillAcosh(Level::kClampParameters)));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillAcosh(Level::kFull)));
+}
+
+TEST_F(BuiltinPolyfillTest, Acosh_Full_f32) {
+ auto* src = R"(
+fn f() {
+ let r : f32 = acosh(1234);
+}
+)";
+
+ auto* expect = R"(
+fn tint_acosh(x : f32) -> f32 {
+ return log((x + sqrt(((x * x) - 1))));
+}
+
+fn f() {
+ let r : f32 = tint_acosh(1234);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillAcosh(Level::kFull));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Acosh_Full_vec3_f32) {
+ auto* src = R"(
+fn f() {
+ let r : vec3<f32> = acosh(vec3<f32>(1234));
+}
+)";
+
+ auto* expect = R"(
+fn tint_acosh(x : vec3<f32>) -> vec3<f32> {
+ return log((x + sqrt(((x * x) - 1))));
+}
+
+fn f() {
+ let r : vec3<f32> = tint_acosh(vec3<f32>(1234));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillAcosh(Level::kFull));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Acosh_Range_f32) {
+ auto* src = R"(
+fn f() {
+ let r : f32 = acosh(1234);
+}
+)";
+
+ auto* expect = R"(
+fn tint_acosh(x : f32) -> f32 {
+ return select(acosh(x), 0.0, (x < 1.0));
+}
+
+fn f() {
+ let r : f32 = tint_acosh(1234);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillAcosh(Level::kRangeCheck));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Acosh_Range_vec3_f32) {
+ auto* src = R"(
+fn f() {
+ let r : vec3<f32> = acosh(vec3<f32>(1234));
+}
+)";
+
+ auto* expect = R"(
+fn tint_acosh(x : vec3<f32>) -> vec3<f32> {
+ return select(acosh(x), vec3<f32>(0.0), (x < vec3<f32>(1.0)));
+}
+
+fn f() {
+ let r : vec3<f32> = tint_acosh(vec3<f32>(1234));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillAcosh(Level::kRangeCheck));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// asinh
+////////////////////////////////////////////////////////////////////////////////
+DataMap polyfillSinh() {
+ BuiltinPolyfill::Builtins builtins;
+ builtins.asinh = true;
+ DataMap data;
+ data.Add<BuiltinPolyfill::Config>(builtins);
+ return data;
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunAsinh) {
+ auto* src = R"(
+fn f() {
+ asinh(1.0);
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillSinh()));
+}
+
+TEST_F(BuiltinPolyfillTest, Asinh_f32) {
+ auto* src = R"(
+fn f() {
+ let r : f32 = asinh(1234);
+}
+)";
+
+ auto* expect = R"(
+fn tint_sinh(x : f32) -> f32 {
+ return log((x + sqrt(((x * x) + 1))));
+}
+
+fn f() {
+ let r : f32 = tint_sinh(1234);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillSinh());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Asinh_vec3_f32) {
+ auto* src = R"(
+fn f() {
+ let r : vec3<f32> = asinh(vec3<f32>(1234));
+}
+)";
+
+ auto* expect = R"(
+fn tint_sinh(x : vec3<f32>) -> vec3<f32> {
+ return log((x + sqrt(((x * x) + 1))));
+}
+
+fn f() {
+ let r : vec3<f32> = tint_sinh(vec3<f32>(1234));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillSinh());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// atanh
+////////////////////////////////////////////////////////////////////////////////
+DataMap polyfillAtanh(Level level) {
+ BuiltinPolyfill::Builtins builtins;
+ builtins.atanh = level;
+ DataMap data;
+ data.Add<BuiltinPolyfill::Config>(builtins);
+ return data;
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunAtanh) {
+ auto* src = R"(
+fn f() {
+ atanh(1.0);
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src, polyfillAtanh(Level::kNone)));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillAtanh(Level::kClampParameters)));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillAtanh(Level::kFull)));
+}
+
+TEST_F(BuiltinPolyfillTest, Atanh_Full_f32) {
+ auto* src = R"(
+fn f() {
+ let r : f32 = atanh(1234);
+}
+)";
+
+ auto* expect = R"(
+fn tint_atanh(x : f32) -> f32 {
+ return (log(((1 + x) / (1 - x))) * 0.5);
+}
+
+fn f() {
+ let r : f32 = tint_atanh(1234);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillAtanh(Level::kFull));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Atanh_Full_vec3_f32) {
+ auto* src = R"(
+fn f() {
+ let r : vec3<f32> = atanh(vec3<f32>(1234));
+}
+)";
+
+ auto* expect = R"(
+fn tint_atanh(x : vec3<f32>) -> vec3<f32> {
+ return (log(((1 + x) / (1 - x))) * 0.5);
+}
+
+fn f() {
+ let r : vec3<f32> = tint_atanh(vec3<f32>(1234));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillAtanh(Level::kFull));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Atanh_Range_f32) {
+ auto* src = R"(
+fn f() {
+ let r : f32 = atanh(1234);
+}
+)";
+
+ auto* expect = R"(
+fn tint_atanh(x : f32) -> f32 {
+ return select(atanh(x), 0.0, (x >= 1.0));
+}
+
+fn f() {
+ let r : f32 = tint_atanh(1234);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillAtanh(Level::kRangeCheck));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Atanh_Range_vec3_f32) {
+ auto* src = R"(
+fn f() {
+ let r : vec3<f32> = atanh(vec3<f32>(1234));
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ let r : vec3<f32> = atanh(vec3<f32>(1234));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillAcosh(Level::kRangeCheck));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+////////////////////////////////////////////////////////////////////////////////
// countLeadingZeros
////////////////////////////////////////////////////////////////////////////////
DataMap polyfillCountLeadingZeros() {
diff --git a/src/tint/transform/canonicalize_entry_point_io.cc b/src/tint/transform/canonicalize_entry_point_io.cc
index 104429b..a324bcc 100644
--- a/src/tint/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/transform/canonicalize_entry_point_io.cc
@@ -196,7 +196,7 @@
value = ctx.dst->IndexAccessor(value, 0_i);
}
}
- ctx.dst->Global(symbol, ast_type, ast::StorageClass::kInput, std::move(attributes));
+ ctx.dst->GlobalVar(symbol, ast_type, ast::StorageClass::kInput, std::move(attributes));
return value;
} else if (cfg.shader_style == ShaderStyle::kMsl &&
ast::HasAttribute<ast::BuiltinAttribute>(attributes)) {
@@ -463,7 +463,7 @@
type = ctx.dst->ty.array(type, 1_u);
lhs = ctx.dst->IndexAccessor(lhs, 0_i);
}
- ctx.dst->Global(name, type, ast::StorageClass::kOutput, std::move(attributes));
+ ctx.dst->GlobalVar(name, type, ast::StorageClass::kOutput, std::move(attributes));
wrapper_body.push_back(ctx.dst->Assign(lhs, outval.value));
}
}
diff --git a/src/tint/transform/combine_samplers.cc b/src/tint/transform/combine_samplers.cc
index cd8395c..4e31789 100644
--- a/src/tint/transform/combine_samplers.cc
+++ b/src/tint/transform/combine_samplers.cc
@@ -19,6 +19,7 @@
#include <utility>
#include <vector>
+#include "src/tint/program_builder.h"
#include "src/tint/sem/function.h"
#include "src/tint/sem/statement.h"
@@ -109,7 +110,7 @@
}
const ast::Type* type = CreateCombinedASTTypeFor(texture_var, sampler_var);
Symbol symbol = ctx.dst->Symbols().New(name);
- return ctx.dst->Global(symbol, type, Attributes());
+ return ctx.dst->GlobalVar(symbol, type, Attributes());
}
/// Creates placeholder global sampler variables.
@@ -121,7 +122,7 @@
? "placeholder_comparison_sampler"
: "placeholder_sampler";
Symbol symbol = ctx.dst->Symbols().New(name);
- return ctx.dst->Global(symbol, type, Attributes());
+ return ctx.dst->GlobalVar(symbol, type, Attributes());
}
/// Creates ast::Type for a given texture and sampler variable pair.
@@ -224,19 +225,21 @@
// Replace all texture builtin calls.
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
const auto& signature = builtin->Signature();
- int sampler_index = signature.IndexOf(sem::ParameterUsage::kSampler);
- int texture_index = signature.IndexOf(sem::ParameterUsage::kTexture);
+ auto sampler_index = signature.IndexOf(sem::ParameterUsage::kSampler);
+ auto texture_index = signature.IndexOf(sem::ParameterUsage::kTexture);
if (texture_index == -1) {
return nullptr;
}
- const sem::Expression* texture = call->Arguments()[texture_index];
+ const sem::Expression* texture =
+ call->Arguments()[static_cast<size_t>(texture_index)];
// We don't want to combine storage textures with anything, since
// they never have associated samplers in GLSL.
if (texture->Type()->UnwrapRef()->Is<sem::StorageTexture>()) {
return nullptr;
}
const sem::Expression* sampler =
- sampler_index != -1 ? call->Arguments()[sampler_index] : nullptr;
+ sampler_index != -1 ? call->Arguments()[static_cast<size_t>(sampler_index)]
+ : nullptr;
auto* texture_var = texture->As<sem::VariableUser>()->Variable();
auto* sampler_var =
sampler ? sampler->As<sem::VariableUser>()->Variable() : nullptr;
diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc
index 32ad153..48dae27 100644
--- a/src/tint/transform/decompose_memory_access.cc
+++ b/src/tint/transform/decompose_memory_access.cc
@@ -377,10 +377,10 @@
auto* lhs_lit = tint::As<OffsetLiteral>(lhs);
auto* rhs_lit = tint::As<OffsetLiteral>(rhs);
if (lhs_lit && lhs_lit->literal == 0) {
- return offsets_.Create<OffsetLiteral>(0);
+ return offsets_.Create<OffsetLiteral>(0u);
}
if (rhs_lit && rhs_lit->literal == 0) {
- return offsets_.Create<OffsetLiteral>(0);
+ return offsets_.Create<OffsetLiteral>(0u);
}
if (lhs_lit && lhs_lit->literal == 1) {
return rhs;
@@ -831,7 +831,7 @@
if (swizzle->Indices().size() == 1) {
if (auto access = state.TakeAccess(accessor->structure)) {
auto* vec_ty = access.type->As<sem::Vector>();
- auto* offset = state.Mul(vec_ty->type()->Size(), swizzle->Indices()[0]);
+ auto* offset = state.Mul(vec_ty->type()->Size(), swizzle->Indices()[0u]);
state.AddAccess(accessor, {
access.var,
state.Add(access.offset, offset),
diff --git a/src/tint/transform/decompose_strided_array_test.cc b/src/tint/transform/decompose_strided_array_test.cc
index ffc6695..65b394a 100644
--- a/src/tint/transform/decompose_strided_array_test.cc
+++ b/src/tint/transform/decompose_strided_array_test.cc
@@ -39,7 +39,7 @@
// var<private> arr : array<f32, 4u>
ProgramBuilder b;
- b.Global("arr", b.ty.array<f32, 4u>(), ast::StorageClass::kPrivate);
+ b.GlobalVar("arr", b.ty.array<f32, 4u>(), ast::StorageClass::kPrivate);
EXPECT_FALSE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
}
@@ -47,7 +47,7 @@
// var<private> arr : @stride(4) array<f32, 4u>
ProgramBuilder b;
- b.Global("arr", b.ty.array<f32, 4u>(4), ast::StorageClass::kPrivate);
+ b.GlobalVar("arr", b.ty.array<f32, 4u>(4), ast::StorageClass::kPrivate);
EXPECT_TRUE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
}
@@ -55,7 +55,7 @@
// var<private> arr : @stride(16) array<f32, 4u>
ProgramBuilder b;
- b.Global("arr", b.ty.array<f32, 4u>(16), ast::StorageClass::kPrivate);
+ b.GlobalVar("arr", b.ty.array<f32, 4u>(16), ast::StorageClass::kPrivate);
EXPECT_TRUE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
}
@@ -78,7 +78,7 @@
// }
ProgramBuilder b;
- b.Global("arr", b.ty.array<f32, 4u>(4), ast::StorageClass::kPrivate);
+ b.GlobalVar("arr", b.ty.array<f32, 4u>(4), ast::StorageClass::kPrivate);
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("a", b.ty.array<f32, 4u>(4), b.Expr("arr"))),
@@ -114,7 +114,7 @@
// }
ProgramBuilder b;
- b.Global("arr", b.ty.array<f32, 4u>(32), ast::StorageClass::kPrivate);
+ b.GlobalVar("arr", b.ty.array<f32, 4u>(32), ast::StorageClass::kPrivate);
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.Expr("arr"))),
@@ -158,7 +158,7 @@
// }
ProgramBuilder b;
auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.MemberAccessor("s", "a"))),
@@ -206,7 +206,7 @@
// }
ProgramBuilder b;
auto* S = b.Structure("S", {b.Member("a", b.ty.array(b.ty.vec4<f32>(), 4_u, 16))});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
b.Func(
"f", {}, b.ty.void_(),
{
@@ -252,7 +252,7 @@
// }
ProgramBuilder b;
auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.MemberAccessor("s", "a"))),
@@ -300,7 +300,7 @@
// }
ProgramBuilder b;
auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(4))});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("a", b.ty.array<f32, 4u>(4), b.MemberAccessor("s", "a"))),
@@ -344,8 +344,8 @@
// }
ProgramBuilder b;
auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4u>(32))),
@@ -398,8 +398,8 @@
// }
ProgramBuilder b;
auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(4))});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4u>(4))),
@@ -450,8 +450,8 @@
// }
ProgramBuilder b;
auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("a", nullptr, b.AddressOf(b.MemberAccessor("s", "a")))),
@@ -511,8 +511,8 @@
ProgramBuilder b;
b.Alias("ARR", b.ty.array<f32, 4u>(32));
auto* S = b.Structure("S", {b.Member("a", b.ty.type_name("ARR"))});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("a", b.ty.type_name("ARR"), b.MemberAccessor("s", "a"))),
@@ -581,8 +581,8 @@
b.ty.array(b.ty.type_name("ARR_A"), 3_u, 16), //
4_u, 128));
auto* S = b.Structure("S", {b.Member("a", b.ty.type_name("ARR_B"))});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("a", b.ty.type_name("ARR_B"), b.MemberAccessor("s", "a"))),
diff --git a/src/tint/transform/decompose_strided_matrix_test.cc b/src/tint/transform/decompose_strided_matrix_test.cc
index 06169d7..daff16f 100644
--- a/src/tint/transform/decompose_strided_matrix_test.cc
+++ b/src/tint/transform/decompose_strided_matrix_test.cc
@@ -71,12 +71,12 @@
"S", {
b.Member("m", b.ty.mat2x2<f32>(),
{
- b.create<ast::StructMemberOffsetAttribute>(16),
- b.create<ast::StrideAttribute>(32),
+ b.create<ast::StructMemberOffsetAttribute>(16u),
+ b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -127,12 +127,12 @@
"S", {
b.Member("m", b.ty.mat2x2<f32>(),
{
- b.create<ast::StructMemberOffsetAttribute>(16),
- b.create<ast::StrideAttribute>(32),
+ b.create<ast::StructMemberOffsetAttribute>(16u),
+ b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
b.Func(
"f", {}, b.ty.void_(),
{
@@ -180,12 +180,12 @@
"S", {
b.Member("m", b.ty.mat2x2<f32>(),
{
- b.create<ast::StructMemberOffsetAttribute>(16),
- b.create<ast::StrideAttribute>(8),
+ b.create<ast::StructMemberOffsetAttribute>(16u),
+ b.create<ast::StrideAttribute>(8u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -233,13 +233,13 @@
"S", {
b.Member("m", b.ty.mat2x2<f32>(),
{
- b.create<ast::StructMemberOffsetAttribute>(8),
- b.create<ast::StrideAttribute>(32),
+ b.create<ast::StructMemberOffsetAttribute>(8u),
+ b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -290,13 +290,13 @@
"S", {
b.Member("m", b.ty.mat2x2<f32>(),
{
- b.create<ast::StructMemberOffsetAttribute>(16),
- b.create<ast::StrideAttribute>(32),
+ b.create<ast::StructMemberOffsetAttribute>(16u),
+ b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ b.GroupAndBinding(0, 0));
b.Func(
"f", {}, b.ty.void_(),
{
@@ -344,13 +344,13 @@
"S", {
b.Member("m", b.ty.mat2x2<f32>(),
{
- b.create<ast::StructMemberOffsetAttribute>(8),
- b.create<ast::StrideAttribute>(32),
+ b.create<ast::StructMemberOffsetAttribute>(8u),
+ b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Assign(b.MemberAccessor("s", "m"),
@@ -402,13 +402,13 @@
"S", {
b.Member("m", b.ty.mat2x2<f32>(),
{
- b.create<ast::StructMemberOffsetAttribute>(8),
- b.create<ast::StrideAttribute>(32),
+ b.create<ast::StructMemberOffsetAttribute>(8u),
+ b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Assign(b.IndexAccessor(b.MemberAccessor("s", "m"), 1_i), b.vec2<f32>(1_f, 2_f)),
@@ -461,13 +461,13 @@
"S", {
b.Member("m", b.ty.mat2x2<f32>(),
{
- b.create<ast::StructMemberOffsetAttribute>(8),
- b.create<ast::StrideAttribute>(32),
+ b.create<ast::StructMemberOffsetAttribute>(8u),
+ b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- b.GroupAndBinding(0, 0));
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ b.GroupAndBinding(0, 0));
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("a", nullptr, b.AddressOf(b.MemberAccessor("s", "m")))),
@@ -532,12 +532,12 @@
"S", {
b.Member("m", b.ty.mat2x2<f32>(),
{
- b.create<ast::StructMemberOffsetAttribute>(8),
- b.create<ast::StrideAttribute>(32),
+ b.create<ast::StructMemberOffsetAttribute>(8u),
+ b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kPrivate);
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kPrivate);
b.Func("f", {}, b.ty.void_(),
{
b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -585,12 +585,12 @@
"S", {
b.Member("m", b.ty.mat2x2<f32>(),
{
- b.create<ast::StructMemberOffsetAttribute>(8),
- b.create<ast::StrideAttribute>(32),
+ b.create<ast::StructMemberOffsetAttribute>(8u),
+ b.create<ast::StrideAttribute>(32u),
b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
}),
});
- b.Global("s", b.ty.Of(S), ast::StorageClass::kPrivate);
+ b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kPrivate);
b.Func("f", {}, b.ty.void_(),
{
b.Assign(b.MemberAccessor("s", "m"),
diff --git a/src/tint/transform/first_index_offset.cc b/src/tint/transform/first_index_offset.cc
index 9d89b83..01f9771 100644
--- a/src/tint/transform/first_index_offset.cc
+++ b/src/tint/transform/first_index_offset.cc
@@ -121,11 +121,12 @@
// Create a global to hold the uniform buffer
Symbol buffer_name = ctx.dst->Sym();
- ctx.dst->Global(buffer_name, ctx.dst->ty.Of(struct_), ast::StorageClass::kUniform, nullptr,
- ast::AttributeList{
- ctx.dst->create<ast::BindingAttribute>(ub_binding),
- ctx.dst->create<ast::GroupAttribute>(ub_group),
- });
+ ctx.dst->GlobalVar(buffer_name, ctx.dst->ty.Of(struct_), ast::StorageClass::kUniform,
+ nullptr,
+ ast::AttributeList{
+ ctx.dst->create<ast::BindingAttribute>(ub_binding),
+ ctx.dst->create<ast::GroupAttribute>(ub_group),
+ });
// Fix up all references to the builtins with the offsets
ctx.ReplaceAll([=, &ctx](const ast::Expression* expr) -> const ast::Expression* {
diff --git a/src/tint/transform/localize_struct_array_assignment.cc b/src/tint/transform/localize_struct_array_assignment.cc
index d6cdded..7c3d695 100644
--- a/src/tint/transform/localize_struct_array_assignment.cc
+++ b/src/tint/transform/localize_struct_array_assignment.cc
@@ -46,7 +46,7 @@
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().IsValid()) {
+ if (!idx_sem->ConstantValue()) {
// Indexing a member access expr?
if (auto* ma = ia->object->As<ast::MemberAccessorExpression>()) {
// That accesses an array?
diff --git a/src/tint/transform/loop_to_for_loop_test.cc b/src/tint/transform/loop_to_for_loop_test.cc
index e3d7ecc..24e0e15 100644
--- a/src/tint/transform/loop_to_for_loop_test.cc
+++ b/src/tint/transform/loop_to_for_loop_test.cc
@@ -151,7 +151,7 @@
)";
auto* expect = R"(
-let N = 16u;
+const N = 16u;
fn f() {
var i : u32 = 0u;
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 cc89fde..5a7eecc 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
@@ -23,6 +23,7 @@
#include "src/tint/program_builder.h"
#include "src/tint/sem/call.h"
#include "src/tint/sem/function.h"
+#include "src/tint/sem/module.h"
#include "src/tint/sem/statement.h"
#include "src/tint/sem/variable.h"
@@ -30,6 +31,10 @@
namespace tint::transform {
namespace {
+
+// The name of the struct member for arrays that are wrapped in structures.
+const char* kWrappedArrayMemberName = "arr";
+
// Returns `true` if `type` is or contains a matrix type.
bool ContainsMatrix(const sem::Type* type) {
type = type->UnwrapRef();
@@ -83,6 +88,192 @@
}
}
+ /// Process a variable `var` that is referenced in the entry point function `func`.
+ /// This will redeclare the variable as a function parameter, possibly as a pointer.
+ /// Some workgroup variables will be redeclared as a member inside a workgroup structure.
+ /// @param func the entry point function
+ /// @param var the variable
+ /// @param new_var_symbol the symbol to use for the replacement
+ /// @param workgroup_param helper function to get a symbol to a workgroup struct parameter
+ /// @param workgroup_parameter_members reference to a list of a workgroup struct members
+ /// @param is_pointer output signalling whether the replacement is a pointer
+ /// @param is_wrapped output signalling whether the replacement is wrapped in a struct
+ void ProcessVariableInEntryPoint(const ast::Function* func,
+ const sem::Variable* var,
+ Symbol new_var_symbol,
+ std::function<Symbol()> workgroup_param,
+ ast::StructMemberList& workgroup_parameter_members,
+ bool& is_pointer,
+ bool& is_wrapped) {
+ auto* var_ast = var->Declaration()->As<ast::Var>();
+ auto* ty = var->Type()->UnwrapRef();
+
+ // Helper to create an AST node for the store type of the variable.
+ auto store_type = [&]() { return CreateASTTypeFor(ctx, ty); };
+
+ ast::StorageClass sc = var->StorageClass();
+ switch (sc) {
+ case ast::StorageClass::kHandle: {
+ // For a texture or sampler variable, redeclare it as an entry point parameter.
+ // Disable entry point parameter validation.
+ auto* disable_validation =
+ ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter);
+ auto attrs = ctx.Clone(var->Declaration()->attributes);
+ attrs.push_back(disable_validation);
+ auto* param = ctx.dst->Param(new_var_symbol, store_type(), attrs);
+ ctx.InsertFront(func->params, param);
+
+ break;
+ }
+ case ast::StorageClass::kStorage:
+ case ast::StorageClass::kUniform: {
+ // Variables into the Storage and Uniform storage classes are redeclared as entry
+ // point parameters with a pointer type.
+ auto attributes = ctx.Clone(var->Declaration()->attributes);
+ attributes.push_back(
+ ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter));
+ attributes.push_back(
+ ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
+
+ auto* param_type = store_type();
+ if (auto* arr = ty->As<sem::Array>(); arr && arr->IsRuntimeSized()) {
+ // Wrap runtime-sized arrays in structures, so that we can declare pointers to
+ // them. Ideally we'd just emit the array itself as a pointer, but this is not
+ // representable in Tint's AST.
+ CloneStructTypes(ty);
+ auto* wrapper = ctx.dst->Structure(
+ ctx.dst->Sym(), {ctx.dst->Member(kWrappedArrayMemberName, param_type)});
+ param_type = ctx.dst->ty.Of(wrapper);
+ is_wrapped = true;
+ }
+
+ param_type = ctx.dst->ty.pointer(param_type, sc, var_ast->declared_access);
+ auto* param = ctx.dst->Param(new_var_symbol, param_type, attributes);
+ ctx.InsertFront(func->params, param);
+ is_pointer = true;
+
+ break;
+ }
+ case ast::StorageClass::kWorkgroup: {
+ if (ContainsMatrix(var->Type())) {
+ // Due to a bug in the MSL compiler, we use a threadgroup memory argument for
+ // any workgroup allocation that contains a matrix. See crbug.com/tint/938.
+ // TODO(jrprice): Do this for all other workgroup variables too.
+
+ // Create a member in the workgroup parameter struct.
+ auto member = ctx.Clone(var->Declaration()->symbol);
+ workgroup_parameter_members.push_back(ctx.dst->Member(member, store_type()));
+ CloneStructTypes(var->Type()->UnwrapRef());
+
+ // Create a function-scope variable that is a pointer to the member.
+ auto* member_ptr = ctx.dst->AddressOf(
+ ctx.dst->MemberAccessor(ctx.dst->Deref(workgroup_param()), member));
+ auto* local_var = ctx.dst->Let(
+ new_var_symbol,
+ ctx.dst->ty.pointer(store_type(), ast::StorageClass::kWorkgroup),
+ member_ptr);
+ ctx.InsertFront(func->body->statements, ctx.dst->Decl(local_var));
+ is_pointer = true;
+
+ break;
+ }
+ [[fallthrough]];
+ }
+ case ast::StorageClass::kPrivate: {
+ // Variables in the Private and Workgroup storage classes are redeclared at function
+ // scope. Disable storage class validation on this variable.
+ auto* disable_validation =
+ ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass);
+ auto* constructor = ctx.Clone(var->Declaration()->constructor);
+ auto* local_var = ctx.dst->Var(new_var_symbol, store_type(), sc, constructor,
+ ast::AttributeList{disable_validation});
+ ctx.InsertFront(func->body->statements, ctx.dst->Decl(local_var));
+
+ break;
+ }
+ default: {
+ TINT_ICE(Transform, ctx.dst->Diagnostics())
+ << "unhandled module-scope storage class (" << sc << ")";
+ }
+ }
+ }
+
+ /// Process a variable `var` that is referenced in the user-defined function `func`.
+ /// This will redeclare the variable as a function parameter, possibly as a pointer.
+ /// @param func the user-defined function
+ /// @param var the variable
+ /// @param new_var_symbol the symbol to use for the replacement
+ /// @param is_pointer output signalling whether the replacement is a pointer or not
+ void ProcessVariableInUserFunction(const ast::Function* func,
+ const sem::Variable* var,
+ Symbol new_var_symbol,
+ bool& is_pointer) {
+ auto* var_ast = var->Declaration()->As<ast::Var>();
+ auto* ty = var->Type()->UnwrapRef();
+ auto* param_type = CreateASTTypeFor(ctx, ty);
+ auto sc = var->StorageClass();
+ switch (sc) {
+ case ast::StorageClass::kPrivate:
+ case ast::StorageClass::kStorage:
+ case ast::StorageClass::kUniform:
+ case ast::StorageClass::kHandle:
+ case ast::StorageClass::kWorkgroup:
+ break;
+ default:
+ TINT_ICE(Transform, ctx.dst->Diagnostics())
+ << "unhandled module-scope storage class (" << sc << ")";
+ }
+
+ // Use a pointer for non-handle types.
+ ast::AttributeList attributes;
+ if (!ty->is_handle()) {
+ param_type = ctx.dst->ty.pointer(param_type, sc, var_ast->declared_access);
+ is_pointer = true;
+
+ // Disable validation of the parameter's storage class and of arguments passed to it.
+ attributes.push_back(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
+ attributes.push_back(
+ ctx.dst->Disable(ast::DisabledValidation::kIgnoreInvalidPointerArgument));
+ }
+
+ // Redeclare the variable as a parameter.
+ ctx.InsertBack(func->params, ctx.dst->Param(new_var_symbol, param_type, attributes));
+ }
+
+ /// Replace all uses of `var` in `func` with references to `new_var`.
+ /// @param func the function
+ /// @param var the variable to replace
+ /// @param new_var the symbol to use for replacement
+ /// @param is_pointer true if `new_var` is a pointer to the new variable
+ /// @param is_wrapped true if `new_var` is an array wrapped in a structure
+ void ReplaceUsesInFunction(const ast::Function* func,
+ const sem::Variable* var,
+ Symbol new_var,
+ bool is_pointer,
+ bool is_wrapped) {
+ for (auto* user : var->Users()) {
+ if (user->Stmt()->Function()->Declaration() == func) {
+ const ast::Expression* expr = ctx.dst->Expr(new_var);
+ if (is_pointer) {
+ // If this identifier is used by an address-of operator, just remove the
+ // address-of instead of adding a deref, since we already have a pointer.
+ auto* ident = user->Declaration()->As<ast::IdentifierExpression>();
+ if (ident_to_address_of_.count(ident)) {
+ ctx.Replace(ident_to_address_of_[ident], expr);
+ continue;
+ }
+
+ expr = ctx.dst->Deref(expr);
+ }
+ if (is_wrapped) {
+ // Get the member from the wrapper structure.
+ expr = ctx.dst->MemberAccessor(expr, kWrappedArrayMemberName);
+ }
+ ctx.Replace(user->Declaration(), expr);
+ }
+ }
+ }
+
/// Process the module.
void Process() {
// Predetermine the list of function calls that need to be replaced.
@@ -91,9 +282,13 @@
std::vector<const ast::Function*> functions_to_process;
- // Build a list of functions that transitively reference any module-scope
- // variables.
- for (auto* func_ast : ctx.src->AST().Functions()) {
+ // Build a list of functions that transitively reference any module-scope variables.
+ for (auto* decl : ctx.src->Sem().Module()->DependencyOrderedDeclarations()) {
+ auto* func_ast = decl->As<ast::Function>();
+ if (!func_ast) {
+ continue;
+ }
+
auto* func_sem = ctx.src->Sem().Get(func_ast);
bool needs_processing = false;
@@ -114,20 +309,18 @@
}
}
- // Build a list of `&ident` expressions. We'll use this later to avoid
- // generating expressions of the form `&*ident`, which break WGSL validation
- // rules when this expression is passed to a function.
- // TODO(jrprice): We should add support for bidirectional SEM tree traversal
- // so that we can do this on the fly instead.
- std::unordered_map<const ast::IdentifierExpression*, const ast::UnaryOpExpression*>
- ident_to_address_of;
+ // Build a list of `&ident` expressions. We'll use this later to avoid generating
+ // expressions of the form `&*ident`, which break WGSL validation rules when this expression
+ // is passed to a function.
+ // TODO(jrprice): We should add support for bidirectional SEM tree traversal so that we can
+ // do this on the fly instead.
for (auto* node : ctx.src->ASTNodes().Objects()) {
auto* address_of = node->As<ast::UnaryOpExpression>();
if (!address_of || address_of->op != ast::UnaryOp::kAddressOf) {
continue;
}
if (auto* ident = address_of->expr->As<ast::IdentifierExpression>()) {
- ident_to_address_of[ident] = address_of;
+ ident_to_address_of_[ident] = address_of;
}
}
@@ -141,11 +334,10 @@
bool is_pointer;
bool is_wrapped;
};
- const char* kWrappedArrayMemberName = "arr";
std::unordered_map<const sem::Variable*, NewVar> var_to_newvar;
- // We aggregate all workgroup variables into a struct to avoid hitting
- // MSL's limit for threadgroup memory arguments.
+ // We aggregate all workgroup variables into a struct to avoid hitting MSL's limit for
+ // threadgroup memory arguments.
Symbol workgroup_parameter_symbol;
ast::StructMemberList workgroup_parameter_members;
auto workgroup_param = [&]() {
@@ -155,159 +347,69 @@
return workgroup_parameter_symbol;
};
- for (auto* global : func_sem->TransitivelyReferencedGlobals()) {
- auto* var = global->Declaration()->As<ast::Var>();
- if (!var) {
+ // Process and redeclare all variables referenced by the function.
+ for (auto* var : func_sem->TransitivelyReferencedGlobals()) {
+ if (var->StorageClass() == ast::StorageClass::kNone) {
continue;
}
- auto sc = global->StorageClass();
- auto* ty = global->Type()->UnwrapRef();
- if (sc == ast::StorageClass::kNone) {
+ if (local_private_vars_.count(var)) {
continue;
}
- if (sc != ast::StorageClass::kPrivate && sc != ast::StorageClass::kStorage &&
- sc != ast::StorageClass::kUniform && sc != ast::StorageClass::kHandle &&
- sc != ast::StorageClass::kWorkgroup) {
- TINT_ICE(Transform, ctx.dst->Diagnostics())
- << "unhandled module-scope storage class (" << sc << ")";
- }
- // This is the symbol for the variable that replaces the module-scope
- // var.
+ // This is the symbol for the variable that replaces the module-scope var.
auto new_var_symbol = ctx.dst->Sym();
- // Helper to create an AST node for the store type of the variable.
- auto store_type = [&]() { return CreateASTTypeFor(ctx, ty); };
-
// Track whether the new variable is a pointer or not.
bool is_pointer = false;
// Track whether the new variable was wrapped in a struct or not.
bool is_wrapped = false;
- if (is_entry_point) {
- if (global->Type()->UnwrapRef()->is_handle()) {
- // For a texture or sampler variable, redeclare it as an entry point
- // parameter. Disable entry point parameter validation.
- auto* disable_validation =
- ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter);
- auto attrs = ctx.Clone(var->attributes);
- attrs.push_back(disable_validation);
- auto* param = ctx.dst->Param(new_var_symbol, store_type(), attrs);
- ctx.InsertFront(func_ast->params, param);
- } else if (sc == ast::StorageClass::kStorage ||
- sc == ast::StorageClass::kUniform) {
- // Variables into the Storage and Uniform storage classes are
- // redeclared as entry point parameters with a pointer type.
- auto attributes = ctx.Clone(var->attributes);
- attributes.push_back(
- ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter));
- attributes.push_back(
- ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
-
- auto* param_type = store_type();
- if (auto* arr = ty->As<sem::Array>(); arr && arr->IsRuntimeSized()) {
- // Wrap runtime-sized arrays in structures, so that we can declare
- // pointers to them. Ideally we'd just emit the array itself as a
- // pointer, but this is not representable in Tint's AST.
- CloneStructTypes(ty);
- auto* wrapper = ctx.dst->Structure(
- ctx.dst->Sym(),
- {ctx.dst->Member(kWrappedArrayMemberName, param_type)});
- param_type = ctx.dst->ty.Of(wrapper);
- is_wrapped = true;
+ // Check if this is a private variable that is only referenced by this function.
+ bool local_private = false;
+ if (var->StorageClass() == ast::StorageClass::kPrivate) {
+ local_private = true;
+ for (auto* user : var->Users()) {
+ auto* stmt = user->Stmt();
+ if (!stmt || stmt->Function() != func_sem) {
+ local_private = false;
+ break;
}
-
- param_type = ctx.dst->ty.pointer(param_type, sc, var->declared_access);
- auto* param = ctx.dst->Param(new_var_symbol, param_type, attributes);
- ctx.InsertFront(func_ast->params, param);
- is_pointer = true;
- } else if (sc == ast::StorageClass::kWorkgroup &&
- ContainsMatrix(global->Type())) {
- // Due to a bug in the MSL compiler, we use a threadgroup memory
- // argument for any workgroup allocation that contains a matrix.
- // See crbug.com/tint/938.
- // TODO(jrprice): Do this for all other workgroup variables too.
-
- // Create a member in the workgroup parameter struct.
- auto member = ctx.Clone(var->symbol);
- workgroup_parameter_members.push_back(
- ctx.dst->Member(member, store_type()));
- CloneStructTypes(global->Type()->UnwrapRef());
-
- // Create a function-scope variable that is a pointer to the member.
- auto* member_ptr = ctx.dst->AddressOf(
- ctx.dst->MemberAccessor(ctx.dst->Deref(workgroup_param()), member));
- auto* local_var = ctx.dst->Let(
- new_var_symbol,
- ctx.dst->ty.pointer(store_type(), ast::StorageClass::kWorkgroup),
- member_ptr);
- ctx.InsertFront(func_ast->body->statements, ctx.dst->Decl(local_var));
- is_pointer = true;
- } else {
- // Variables in the Private and Workgroup storage classes are
- // redeclared at function scope. Disable storage class validation on
- // this variable.
- auto* disable_validation =
- ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass);
- auto* constructor = ctx.Clone(var->constructor);
- auto* local_var =
- ctx.dst->Var(new_var_symbol, store_type(), sc, constructor,
- ast::AttributeList{disable_validation});
- ctx.InsertFront(func_ast->body->statements, ctx.dst->Decl(local_var));
}
+ }
+
+ if (local_private) {
+ // Redeclare the variable at function scope.
+ auto* disable_validation =
+ ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass);
+ auto* constructor = ctx.Clone(var->Declaration()->constructor);
+ auto* local_var = ctx.dst->Var(new_var_symbol,
+ CreateASTTypeFor(ctx, var->Type()->UnwrapRef()),
+ ast::StorageClass::kPrivate, constructor,
+ ast::AttributeList{disable_validation});
+ ctx.InsertFront(func_ast->body->statements, ctx.dst->Decl(local_var));
+ local_private_vars_.insert(var);
} else {
- // For a regular function, redeclare the variable as a parameter.
- // Use a pointer for non-handle types.
- auto* param_type = store_type();
- ast::AttributeList attributes;
- if (!global->Type()->UnwrapRef()->is_handle()) {
- param_type = ctx.dst->ty.pointer(param_type, sc, var->declared_access);
- is_pointer = true;
-
- // Disable validation of the parameter's storage class and of
- // arguments passed it.
- attributes.push_back(
- ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
- attributes.push_back(ctx.dst->Disable(
- ast::DisabledValidation::kIgnoreInvalidPointerArgument));
+ // Process the variable to redeclare it as a parameter or local variable.
+ if (is_entry_point) {
+ ProcessVariableInEntryPoint(func_ast, var, new_var_symbol, workgroup_param,
+ workgroup_parameter_members, is_pointer,
+ is_wrapped);
+ } else {
+ ProcessVariableInUserFunction(func_ast, var, new_var_symbol, is_pointer);
}
- ctx.InsertBack(func_ast->params,
- ctx.dst->Param(new_var_symbol, param_type, attributes));
+
+ // Record the replacement symbol.
+ var_to_newvar[var] = {new_var_symbol, is_pointer, is_wrapped};
}
// Replace all uses of the module-scope variable.
- // For non-entry points, dereference non-handle pointer parameters.
- for (auto* user : global->Users()) {
- if (user->Stmt()->Function()->Declaration() == func_ast) {
- const ast::Expression* expr = ctx.dst->Expr(new_var_symbol);
- if (is_pointer) {
- // If this identifier is used by an address-of operator, just
- // remove the address-of instead of adding a deref, since we
- // already have a pointer.
- auto* ident = user->Declaration()->As<ast::IdentifierExpression>();
- if (ident_to_address_of.count(ident)) {
- ctx.Replace(ident_to_address_of[ident], expr);
- continue;
- }
-
- expr = ctx.dst->Deref(expr);
- }
- if (is_wrapped) {
- // Get the member from the wrapper structure.
- expr = ctx.dst->MemberAccessor(expr, kWrappedArrayMemberName);
- }
- ctx.Replace(user->Declaration(), expr);
- }
- }
-
- var_to_newvar[global] = {new_var_symbol, is_pointer, is_wrapped};
+ ReplaceUsesInFunction(func_ast, var, new_var_symbol, is_pointer, is_wrapped);
}
if (!workgroup_parameter_members.empty()) {
// Create the workgroup memory parameter.
- // The parameter is a struct that contains members for each workgroup
- // variable.
+ // The parameter is a struct that contains members for each workgroup variable.
auto* str =
ctx.dst->Structure(ctx.dst->Sym(), std::move(workgroup_parameter_members));
auto* param_type =
@@ -331,12 +433,18 @@
continue;
}
- auto new_var = var_to_newvar[target_var];
+ auto it = var_to_newvar.find(target_var);
+ if (it == var_to_newvar.end()) {
+ // No replacement was created for this function.
+ continue;
+ }
+
+ auto new_var = it->second;
bool is_handle = target_var->Type()->UnwrapRef()->is_handle();
const ast::Expression* arg = ctx.dst->Expr(new_var.symbol);
if (new_var.is_wrapped) {
- // The variable is wrapped in a struct, so we need to pass a pointer
- // to the struct member instead.
+ // The variable is wrapped in a struct, so we need to pass a pointer to the
+ // struct member instead.
arg = ctx.dst->AddressOf(
ctx.dst->MemberAccessor(ctx.dst->Deref(arg), kWrappedArrayMemberName));
} else if (is_entry_point && !is_handle && !new_var.is_pointer) {
@@ -359,7 +467,15 @@
}
private:
+ // The structures that have already been cloned by this transform.
std::unordered_set<const sem::Struct*> cloned_structs_;
+
+ // Set of a private variables that are local to a single function.
+ std::unordered_set<const sem::Variable*> local_private_vars_;
+
+ // Map from identifier expression to the address-of expression that uses it.
+ std::unordered_map<const ast::IdentifierExpression*, const ast::UnaryOpExpression*>
+ ident_to_address_of_;
};
ModuleScopeVarToEntryPointParam::ModuleScopeVarToEntryPointParam() = default;
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param_test.cc b/src/tint/transform/module_scope_var_to_entry_point_param_test.cc
index 9e81d31..dcf8912 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param_test.cc
+++ b/src/tint/transform/module_scope_var_to_entry_point_param_test.cc
@@ -95,9 +95,14 @@
fn no_uses() {
}
+fn zoo() {
+ p = p * 2.0;
+}
+
fn bar(a : f32, b : f32) {
p = a;
w = b;
+ zoo();
}
fn foo(a : f32) {
@@ -116,22 +121,27 @@
fn no_uses() {
}
-fn bar(a : f32, b : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<workgroup, f32>) {
- *(tint_symbol) = a;
- *(tint_symbol_1) = b;
+fn zoo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<private, f32>) {
+ *(tint_symbol) = (*(tint_symbol) * 2.0);
}
-fn foo(a : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<workgroup, f32>) {
+fn bar(a : f32, b : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<workgroup, f32>) {
+ *(tint_symbol_1) = a;
+ *(tint_symbol_2) = b;
+ zoo(tint_symbol_1);
+}
+
+fn foo(a : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_4 : ptr<workgroup, f32>) {
let b : f32 = 2.0;
- bar(a, b, tint_symbol_2, tint_symbol_3);
+ bar(a, b, tint_symbol_3, tint_symbol_4);
no_uses();
}
@compute @workgroup_size(1)
fn main() {
- @internal(disable_validation__ignore_storage_class) var<private> tint_symbol_4 : f32;
- @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_5 : f32;
- foo(1.0, &(tint_symbol_4), &(tint_symbol_5));
+ @internal(disable_validation__ignore_storage_class) var<private> tint_symbol_5 : f32;
+ @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_6 : f32;
+ foo(1.0, &(tint_symbol_5), &(tint_symbol_6));
}
)";
@@ -159,6 +169,11 @@
fn bar(a : f32, b : f32) {
p = a;
w = b;
+ zoo();
+}
+
+fn zoo() {
+ p = p * 2.0;
}
var<private> p : f32;
@@ -168,23 +183,28 @@
auto* expect = R"(
@compute @workgroup_size(1)
fn main() {
- @internal(disable_validation__ignore_storage_class) var<private> tint_symbol : f32;
- @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_1 : f32;
- foo(1.0, &(tint_symbol), &(tint_symbol_1));
+ @internal(disable_validation__ignore_storage_class) var<private> tint_symbol_5 : f32;
+ @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_6 : f32;
+ foo(1.0, &(tint_symbol_5), &(tint_symbol_6));
}
-fn foo(a : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<workgroup, f32>) {
+fn foo(a : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_4 : ptr<workgroup, f32>) {
let b : f32 = 2.0;
- bar(a, b, tint_symbol_2, tint_symbol_3);
+ bar(a, b, tint_symbol_3, tint_symbol_4);
no_uses();
}
fn no_uses() {
}
-fn bar(a : f32, b : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_4 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_5 : ptr<workgroup, f32>) {
- *(tint_symbol_4) = a;
- *(tint_symbol_5) = b;
+fn bar(a : f32, b : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<workgroup, f32>) {
+ *(tint_symbol_1) = a;
+ *(tint_symbol_2) = b;
+ zoo(tint_symbol_1);
+}
+
+fn zoo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<private, f32>) {
+ *(tint_symbol) = (*(tint_symbol) * 2.0);
}
)";
@@ -307,9 +327,9 @@
TEST_F(ModuleScopeVarToEntryPointParamTest, FoldAddressOfDeref) {
auto* src = R"(
-var<private> v : f32;
+var<workgroup> v : f32;
-fn bar(p : ptr<private, f32>) {
+fn bar(p : ptr<workgroup, f32>) {
(*p) = 0.0;
}
@@ -324,17 +344,17 @@
)";
auto* expect = R"(
-fn bar(p : ptr<private, f32>) {
+fn bar(p : ptr<workgroup, f32>) {
*(p) = 0.0;
}
-fn foo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<private, f32>) {
+fn foo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<workgroup, f32>) {
bar(tint_symbol);
}
@compute @workgroup_size(1)
fn main() {
- @internal(disable_validation__ignore_storage_class) var<private> tint_symbol_1 : f32;
+ @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_1 : f32;
foo(&(tint_symbol_1));
}
)";
@@ -355,25 +375,25 @@
bar(&v);
}
-fn bar(p : ptr<private, f32>) {
+fn bar(p : ptr<workgroup, f32>) {
(*p) = 0.0;
}
-var<private> v : f32;
+var<workgroup> v : f32;
)";
auto* expect = R"(
@compute @workgroup_size(1)
fn main() {
- @internal(disable_validation__ignore_storage_class) var<private> tint_symbol : f32;
- foo(&(tint_symbol));
+ @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_1 : f32;
+ foo(&(tint_symbol_1));
}
-fn foo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<private, f32>) {
- bar(tint_symbol_1);
+fn foo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<workgroup, f32>) {
+ bar(tint_symbol);
}
-fn bar(p : ptr<private, f32>) {
+fn bar(p : ptr<workgroup, f32>) {
*(p) = 0.0;
}
)";
@@ -556,17 +576,17 @@
)";
auto* expect = R"(
-struct tint_symbol_1 {
+struct tint_symbol_2 {
arr : array<f32>,
}
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol : ptr<storage, tint_symbol_1>) {
- foo(&((*(tint_symbol)).arr));
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_1 : ptr<storage, tint_symbol_2>) {
+ foo(&((*(tint_symbol_1)).arr));
}
-fn foo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<storage, array<f32>>) {
- _ = (*(tint_symbol_2))[0];
+fn foo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<storage, array<f32>>) {
+ _ = (*(tint_symbol))[0];
}
)";
@@ -802,8 +822,8 @@
auto* expect = R"(
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_1 : ptr<storage, S>) {
- foo(1.0, tint_symbol, tint_symbol_1);
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_4 : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_5 : ptr<storage, S>) {
+ foo(1.0, tint_symbol_4, tint_symbol_5);
}
fn foo(a : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<uniform, S>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<storage, S>) {
@@ -816,9 +836,9 @@
fn no_uses() {
}
-fn bar(a : f32, b : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_4 : ptr<uniform, S>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_5 : ptr<storage, S>) {
- _ = *(tint_symbol_4);
- _ = *(tint_symbol_5);
+fn bar(a : f32, b : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<uniform, S>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<storage, S>) {
+ _ = *(tint_symbol);
+ _ = *(tint_symbol_1);
}
struct S {
@@ -937,8 +957,8 @@
auto* expect = R"(
@compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) tint_symbol : texture_2d<f32>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) tint_symbol_1 : sampler) {
- foo(1.0, tint_symbol, tint_symbol_1);
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) tint_symbol_4 : texture_2d<f32>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) tint_symbol_5 : sampler) {
+ foo(1.0, tint_symbol_4, tint_symbol_5);
}
fn foo(a : f32, tint_symbol_2 : texture_2d<f32>, tint_symbol_3 : sampler) {
@@ -951,9 +971,9 @@
fn no_uses() {
}
-fn bar(a : f32, b : f32, tint_symbol_4 : texture_2d<f32>, tint_symbol_5 : sampler) {
- _ = tint_symbol_4;
- _ = tint_symbol_5;
+fn bar(a : f32, b : f32, tint_symbol : texture_2d<f32>, tint_symbol_1 : sampler) {
+ _ = tint_symbol;
+ _ = tint_symbol_1;
}
)";
@@ -1152,6 +1172,81 @@
EXPECT_EQ(expect, str(got));
}
+// Test that a private variable that is only referenced by a single user-defined function is
+// promoted to a function scope variable, rather than passed as a parameter.
+TEST_F(ModuleScopeVarToEntryPointParamTest, PromotePrivateToFunctionScope) {
+ auto* src = R"(
+var<private> p : f32;
+
+fn foo(a : f32) -> f32 {
+ let x = p;
+ p = x * a;
+ return p;
+}
+
+@compute @workgroup_size(1)
+fn main() {
+ _ = foo(1.0);
+}
+)";
+
+ auto* expect = R"(
+fn foo(a : f32) -> f32 {
+ @internal(disable_validation__ignore_storage_class) var<private> tint_symbol : f32;
+ let x = tint_symbol;
+ tint_symbol = (x * a);
+ return tint_symbol;
+}
+
+@compute @workgroup_size(1)
+fn main() {
+ _ = foo(1.0);
+}
+)";
+
+ auto got = Run<ModuleScopeVarToEntryPointParam>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+// Test that a private variable that is only referenced by a single user-defined function is
+// promoted to a function scope variable, rather than passed as a parameter.
+TEST_F(ModuleScopeVarToEntryPointParamTest, PromotePrivateToFunctionScope_OutOfOrder) {
+ auto* src = R"(
+var<private> p : f32;
+
+@compute @workgroup_size(1)
+fn main() {
+ _ = foo(1.0);
+}
+
+fn foo(a : f32) -> f32 {
+ let x = p;
+ p = x * a;
+ return p;
+}
+
+)";
+
+ auto* expect = R"(
+@compute @workgroup_size(1)
+fn main() {
+ _ = foo(1.0);
+}
+
+fn foo(a : f32) -> f32 {
+ @internal(disable_validation__ignore_storage_class) var<private> tint_symbol : f32;
+ let x = tint_symbol;
+ tint_symbol = (x * a);
+ return tint_symbol;
+}
+)";
+
+ auto got = Run<ModuleScopeVarToEntryPointParam>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
TEST_F(ModuleScopeVarToEntryPointParamTest, EmtpyModule) {
auto* src = "";
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index 8b85573..c3aba9b 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -131,12 +131,12 @@
auto& syms = new_binding_symbols[sem_var];
syms.plane_0 = ctx.Clone(global->symbol);
syms.plane_1 = b.Symbols().New("ext_tex_plane_1");
- b.Global(syms.plane_1, b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
- b.GroupAndBinding(bps.plane_1.group, bps.plane_1.binding));
+ b.GlobalVar(syms.plane_1, b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
+ b.GroupAndBinding(bps.plane_1.group, bps.plane_1.binding));
syms.params = b.Symbols().New("ext_tex_params");
- b.Global(syms.params, b.ty.type_name("ExternalTextureParams"),
- ast::StorageClass::kUniform,
- b.GroupAndBinding(bps.params.group, bps.params.binding));
+ b.GlobalVar(syms.params, b.ty.type_name("ExternalTextureParams"),
+ ast::StorageClass::kUniform,
+ b.GroupAndBinding(bps.params.group, bps.params.binding));
// Replace the original texture_external binding with a texture_2d<f32>
// binding.
@@ -251,6 +251,7 @@
// Create ExternalTextureParams struct.
ast::StructMemberList ext_tex_params_member_list = {
b.Member("numPlanes", b.ty.u32()),
+ b.Member("doYuvToRgbConversionOnly", b.ty.u32()),
b.Member("yuvToRgbConversionMatrix", b.ty.mat3x4(b.ty.f32())),
b.Member("gammaDecodeParams", b.ty.type_name("GammaTransferParams")),
b.Member("gammaEncodeParams", b.ty.type_name("GammaTransferParams")),
@@ -340,14 +341,20 @@
b.Mul(b.vec4<f32>(b.MemberAccessor(plane_0_call, "r"),
b.MemberAccessor(plane_1_call, "rg"), 1_f),
b.MemberAccessor("params", "yuvToRgbConversionMatrix")))))),
- // color = gammaConversion(color, gammaDecodeParams);
- b.Assign("color", b.Call("gammaCorrection", "color",
- b.MemberAccessor("params", "gammaDecodeParams"))),
- // color = (params.gamutConversionMatrix * color);
- b.Assign("color", b.Mul(b.MemberAccessor("params", "gamutConversionMatrix"), "color")),
- // color = gammaConversion(color, gammaEncodeParams);
- b.Assign("color", b.Call("gammaCorrection", "color",
- b.MemberAccessor("params", "gammaEncodeParams"))),
+ // if (params.doYuvToRgbConversionOnly == 0u)
+ b.If(b.create<ast::BinaryExpression>(
+ ast::BinaryOp::kEqual, b.MemberAccessor("params", "doYuvToRgbConversionOnly"),
+ b.Expr(0_u)),
+ b.Block(
+ // color = gammaConversion(color, gammaDecodeParams);
+ b.Assign("color", b.Call("gammaCorrection", "color",
+ b.MemberAccessor("params", "gammaDecodeParams"))),
+ // color = (params.gamutConversionMatrix * color);
+ b.Assign("color",
+ b.Mul(b.MemberAccessor("params", "gamutConversionMatrix"), "color")),
+ // color = gammaConversion(color, gammaEncodeParams);
+ b.Assign("color", b.Call("gammaCorrection", "color",
+ b.MemberAccessor("params", "gammaEncodeParams"))))),
// return vec4<f32>(color, 1.f);
b.Return(b.vec4<f32>("color", 1_f))};
}
diff --git a/src/tint/transform/multiplanar_external_texture.h b/src/tint/transform/multiplanar_external_texture.h
index 88cbc98..fcb5156 100644
--- a/src/tint/transform/multiplanar_external_texture.h
+++ b/src/tint/transform/multiplanar_external_texture.h
@@ -46,7 +46,10 @@
/// textureSampleLevel 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 seperate Y and UV
-/// planes.
+/// planes, and do colorspace conversions including yuv->rgb conversion, gamma
+/// decoding, gamut conversion, and gamma encoding steps. Specifically
+// for BT.709 to SRGB conversion, it takes the fast path only doing the yuv->rgb
+// step and skipping all other steps.
class MultiplanarExternalTexture : public Castable<MultiplanarExternalTexture, Transform> {
public:
/// BindingsMap is a map where the key is the binding location of a
diff --git a/src/tint/transform/multiplanar_external_texture_test.cc b/src/tint/transform/multiplanar_external_texture_test.cc
index 63d12f1..79f9fdd 100644
--- a/src/tint/transform/multiplanar_external_texture_test.cc
+++ b/src/tint/transform/multiplanar_external_texture_test.cc
@@ -118,6 +118,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -172,6 +173,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -225,6 +227,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -253,9 +256,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -298,6 +303,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -322,9 +328,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -370,6 +378,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -396,9 +405,11 @@
} else {
color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -440,6 +451,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -464,9 +476,11 @@
} else {
color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -512,6 +526,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -540,9 +555,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -553,9 +570,11 @@
} else {
color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -599,6 +618,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -623,9 +643,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -636,9 +658,11 @@
} else {
color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -688,6 +712,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -734,9 +759,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -788,6 +815,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -812,9 +840,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -870,6 +900,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -899,9 +930,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -952,6 +985,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -976,9 +1010,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -1036,6 +1072,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -1064,9 +1101,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -1129,6 +1168,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -1162,9 +1202,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -1223,6 +1265,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -1247,9 +1290,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -1313,6 +1358,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -1337,9 +1383,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -1391,6 +1439,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -1441,6 +1490,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -1467,9 +1517,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
@@ -1526,6 +1578,7 @@
struct ExternalTextureParams {
numPlanes : u32,
+ doYuvToRgbConversionOnly : u32,
yuvToRgbConversionMatrix : mat3x4<f32>,
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
@@ -1555,9 +1608,11 @@
} else {
color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix);
}
- color = gammaCorrection(color, params.gammaDecodeParams);
- color = (params.gamutConversionMatrix * color);
- color = gammaCorrection(color, params.gammaEncodeParams);
+ if ((params.doYuvToRgbConversionOnly == 0u)) {
+ color = gammaCorrection(color, params.gammaDecodeParams);
+ color = (params.gamutConversionMatrix * color);
+ color = gammaCorrection(color, params.gammaEncodeParams);
+ }
return vec4<f32>(color, 1.0f);
}
diff --git a/src/tint/transform/num_workgroups_from_uniform.cc b/src/tint/transform/num_workgroups_from_uniform.cc
index bba1580..6b93e73 100644
--- a/src/tint/transform/num_workgroups_from_uniform.cc
+++ b/src/tint/transform/num_workgroups_from_uniform.cc
@@ -144,7 +144,7 @@
binding = 0;
}
- num_workgroups_ubo = ctx.dst->Global(
+ num_workgroups_ubo = ctx.dst->GlobalVar(
ctx.dst->Sym(), ctx.dst->ty.Of(num_workgroups_struct), ast::StorageClass::kUniform,
ast::AttributeList{ctx.dst->GroupAndBinding(group, binding)});
}
diff --git a/src/tint/transform/promote_initializers_to_const_var.cc b/src/tint/transform/promote_initializers_to_const_var.cc
deleted file mode 100644
index 6e0ba55..0000000
--- a/src/tint/transform/promote_initializers_to_const_var.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// 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/transform/promote_initializers_to_const_var.h"
-#include "src/tint/program_builder.h"
-#include "src/tint/sem/call.h"
-#include "src/tint/sem/statement.h"
-#include "src/tint/sem/type_constructor.h"
-#include "src/tint/transform/utils/hoist_to_decl_before.h"
-
-TINT_INSTANTIATE_TYPEINFO(tint::transform::PromoteInitializersToConstVar);
-
-namespace tint::transform {
-
-PromoteInitializersToConstVar::PromoteInitializersToConstVar() = default;
-
-PromoteInitializersToConstVar::~PromoteInitializersToConstVar() = default;
-
-void PromoteInitializersToConstVar::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- HoistToDeclBefore hoist_to_decl_before(ctx);
-
- // Hoists array and structure initializers to a constant variable, declared
- // just before the statement of usage.
- auto type_ctor_to_let = [&](const ast::CallExpression* expr) {
- auto* ctor = ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
- if (!ctor->Target()->Is<sem::TypeConstructor>()) {
- return true;
- }
- auto* sem_stmt = ctor->Stmt();
- if (!sem_stmt) {
- // Expression is outside of a statement. This usually means the
- // expression is part of a global (module-scope) constant declaration.
- // These must be constexpr, and so cannot contain the type of
- // expressions that must be sanitized.
- return true;
- }
-
- auto* stmt = sem_stmt->Declaration();
-
- if (auto* src_var_decl = stmt->As<ast::VariableDeclStatement>()) {
- if (src_var_decl->variable->constructor == expr) {
- // This statement is just a variable declaration with the
- // initializer as the constructor value. This is what we're
- // attempting to transform to, and so ignore.
- return true;
- }
- }
-
- auto* src_ty = ctor->Type();
- if (!src_ty->IsAnyOf<sem::Array, sem::Struct>()) {
- // We only care about array and struct initializers
- return true;
- }
-
- return hoist_to_decl_before.Add(ctor, expr, true);
- };
-
- for (auto* node : ctx.src->ASTNodes().Objects()) {
- if (auto* call_expr = node->As<ast::CallExpression>()) {
- if (!type_ctor_to_let(call_expr)) {
- return;
- }
- }
- }
-
- hoist_to_decl_before.Apply();
- ctx.Clone();
-}
-
-} // namespace tint::transform
diff --git a/src/tint/transform/promote_initializers_to_const_var_test.cc b/src/tint/transform/promote_initializers_to_const_var_test.cc
deleted file mode 100644
index f322478..0000000
--- a/src/tint/transform/promote_initializers_to_const_var_test.cc
+++ /dev/null
@@ -1,625 +0,0 @@
-// Copyright 2021 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/transform/promote_initializers_to_const_var.h"
-
-#include "src/tint/transform/test_helper.h"
-
-namespace tint::transform {
-namespace {
-
-using PromoteInitializersToConstVarTest = TransformTest;
-
-TEST_F(PromoteInitializersToConstVarTest, EmptyModule) {
- auto* src = "";
- auto* expect = "";
-
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, BasicArray) {
- auto* src = R"(
-fn f() {
- var f0 = 1.0;
- var f1 = 2.0;
- var f2 = 3.0;
- var f3 = 4.0;
- var i = array<f32, 4u>(f0, f1, f2, f3)[2];
-}
-)";
-
- auto* expect = R"(
-fn f() {
- var f0 = 1.0;
- var f1 = 2.0;
- var f2 = 3.0;
- var f3 = 4.0;
- let tint_symbol = array<f32, 4u>(f0, f1, f2, f3);
- var i = tint_symbol[2];
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, BasicStruct) {
- auto* src = R"(
-struct S {
- a : i32,
- b : f32,
- c : vec3<f32>,
-};
-
-fn f() {
- var x = S(1, 2.0, vec3<f32>()).b;
-}
-)";
-
- auto* expect = R"(
-struct S {
- a : i32,
- b : f32,
- c : vec3<f32>,
-}
-
-fn f() {
- let tint_symbol = S(1, 2.0, vec3<f32>());
- var x = tint_symbol.b;
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, BasicStruct_OutOfOrder) {
- auto* src = R"(
-fn f() {
- var x = S(1, 2.0, vec3<f32>()).b;
-}
-
-struct S {
- a : i32,
- b : f32,
- c : vec3<f32>,
-};
-)";
-
- auto* expect = R"(
-fn f() {
- let tint_symbol = S(1, 2.0, vec3<f32>());
- var x = tint_symbol.b;
-}
-
-struct S {
- a : i32,
- b : f32,
- c : vec3<f32>,
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, ArrayInForLoopInit) {
- auto* src = R"(
-fn f() {
- var insert_after = 1;
- for(var i = array<f32, 4u>(0.0, 1.0, 2.0, 3.0)[2]; ; ) {
- break;
- }
-}
-)";
-
- auto* expect = R"(
-fn f() {
- var insert_after = 1;
- let tint_symbol = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
- for(var i = tint_symbol[2]; ; ) {
- break;
- }
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, StructInForLoopInit) {
- auto* src = R"(
-struct S {
- a : i32,
- b : f32,
- c : vec3<f32>,
-};
-
-fn f() {
- var insert_after = 1;
- for(var x = S(1, 2.0, vec3<f32>()).b; ; ) {
- break;
- }
-}
-)";
-
- auto* expect = R"(
-struct S {
- a : i32,
- b : f32,
- c : vec3<f32>,
-}
-
-fn f() {
- var insert_after = 1;
- let tint_symbol = S(1, 2.0, vec3<f32>());
- for(var x = tint_symbol.b; ; ) {
- break;
- }
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, StructInForLoopInit_OutOfOrder) {
- auto* src = R"(
-fn f() {
- var insert_after = 1;
- for(var x = S(1, 2.0, vec3<f32>()).b; ; ) {
- break;
- }
-}
-
-struct S {
- a : i32,
- b : f32,
- c : vec3<f32>,
-};
-)";
-
- auto* expect = R"(
-fn f() {
- var insert_after = 1;
- let tint_symbol = S(1, 2.0, vec3<f32>());
- for(var x = tint_symbol.b; ; ) {
- break;
- }
-}
-
-struct S {
- a : i32,
- b : f32,
- c : vec3<f32>,
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, ArrayInForLoopCond) {
- auto* src = R"(
-fn f() {
- var f = 1.0;
- for(; f == array<f32, 1u>(f)[0]; f = f + 1.0) {
- var marker = 1;
- }
-}
-)";
-
- auto* expect = R"(
-fn f() {
- var f = 1.0;
- loop {
- let tint_symbol = array<f32, 1u>(f);
- if (!((f == tint_symbol[0]))) {
- break;
- }
- {
- var marker = 1;
- }
-
- continuing {
- f = (f + 1.0);
- }
- }
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, ArrayInForLoopCont) {
- auto* src = R"(
-fn f() {
- var f = 0.0;
- for(; f < 10.0; f = f + array<f32, 1u>(1.0)[0]) {
- var marker = 1;
- }
-}
-)";
-
- auto* expect = R"(
-fn f() {
- var f = 0.0;
- loop {
- if (!((f < 10.0))) {
- break;
- }
- {
- var marker = 1;
- }
-
- continuing {
- let tint_symbol = array<f32, 1u>(1.0);
- f = (f + tint_symbol[0]);
- }
- }
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, ArrayInForLoopInitCondCont) {
- auto* src = R"(
-fn f() {
- for(var f = array<f32, 1u>(0.0)[0];
- f < array<f32, 1u>(1.0)[0];
- f = f + array<f32, 1u>(2.0)[0]) {
- var marker = 1;
- }
-}
-)";
-
- auto* expect = R"(
-fn f() {
- let tint_symbol = array<f32, 1u>(0.0);
- {
- var f = tint_symbol[0];
- loop {
- let tint_symbol_1 = array<f32, 1u>(1.0);
- if (!((f < tint_symbol_1[0]))) {
- break;
- }
- {
- var marker = 1;
- }
-
- continuing {
- let tint_symbol_2 = array<f32, 1u>(2.0);
- f = (f + tint_symbol_2[0]);
- }
- }
- }
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, ArrayInElseIf) {
- auto* src = R"(
-fn f() {
- var f = 1.0;
- if (true) {
- var marker = 0;
- } else if (f == array<f32, 2u>(f, f)[0]) {
- var marker = 1;
- }
-}
-)";
-
- auto* expect = R"(
-fn f() {
- var f = 1.0;
- if (true) {
- var marker = 0;
- } else {
- let tint_symbol = array<f32, 2u>(f, f);
- if ((f == tint_symbol[0])) {
- var marker = 1;
- }
- }
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, ArrayInElseIfChain) {
- auto* src = R"(
-fn f() {
- var f = 1.0;
- if (true) {
- var marker = 0;
- } else if (true) {
- var marker = 1;
- } else if (f == array<f32, 2u>(f, f)[0]) {
- var marker = 2;
- } else if (f == array<f32, 2u>(f, f)[1]) {
- var marker = 3;
- } else if (true) {
- var marker = 4;
- } else {
- var marker = 5;
- }
-}
-)";
-
- auto* expect = R"(
-fn f() {
- var f = 1.0;
- if (true) {
- var marker = 0;
- } else if (true) {
- var marker = 1;
- } else {
- let tint_symbol = array<f32, 2u>(f, f);
- if ((f == tint_symbol[0])) {
- var marker = 2;
- } else {
- let tint_symbol_1 = array<f32, 2u>(f, f);
- if ((f == tint_symbol_1[1])) {
- var marker = 3;
- } else if (true) {
- var marker = 4;
- } else {
- var marker = 5;
- }
- }
- }
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, ArrayInArrayArray) {
- auto* src = R"(
-fn f() {
- var i = array<array<f32, 2u>, 2u>(array<f32, 2u>(1.0, 2.0), array<f32, 2u>(3.0, 4.0))[0][1];
-}
-)";
-
- auto* expect = R"(
-fn f() {
- let tint_symbol = array<f32, 2u>(1.0, 2.0);
- let tint_symbol_1 = array<f32, 2u>(3.0, 4.0);
- let tint_symbol_2 = array<array<f32, 2u>, 2u>(tint_symbol, tint_symbol_1);
- var i = tint_symbol_2[0][1];
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, StructNested) {
- auto* src = R"(
-struct S1 {
- a : i32,
-};
-
-struct S2 {
- a : i32,
- b : S1,
- c : i32,
-};
-
-struct S3 {
- a : S2,
-};
-
-fn f() {
- var x = S3(S2(1, S1(2), 3)).a.b.a;
-}
-)";
-
- auto* expect = R"(
-struct S1 {
- a : i32,
-}
-
-struct S2 {
- a : i32,
- b : S1,
- c : i32,
-}
-
-struct S3 {
- a : S2,
-}
-
-fn f() {
- let tint_symbol = S1(2);
- let tint_symbol_1 = S2(1, tint_symbol, 3);
- let tint_symbol_2 = S3(tint_symbol_1);
- var x = tint_symbol_2.a.b.a;
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, Mixed) {
- auto* src = R"(
-struct S1 {
- a : i32,
-};
-
-struct S2 {
- a : array<S1, 3u>,
-};
-
-fn f() {
- var x = S2(array<S1, 3u>(S1(1), S1(2), S1(3))).a[1].a;
-}
-)";
-
- auto* expect = R"(
-struct S1 {
- a : i32,
-}
-
-struct S2 {
- a : array<S1, 3u>,
-}
-
-fn f() {
- let tint_symbol = S1(1);
- let tint_symbol_1 = S1(2);
- let tint_symbol_2 = S1(3);
- let tint_symbol_3 = array<S1, 3u>(tint_symbol, tint_symbol_1, tint_symbol_2);
- let tint_symbol_4 = S2(tint_symbol_3);
- var x = tint_symbol_4.a[1].a;
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, Mixed_OutOfOrder) {
- auto* src = R"(
-fn f() {
- var x = S2(array<S1, 3u>(S1(1), S1(2), S1(3))).a[1].a;
-}
-
-struct S2 {
- a : array<S1, 3u>,
-};
-
-struct S1 {
- a : i32,
-};
-)";
-
- auto* expect = R"(
-fn f() {
- let tint_symbol = S1(1);
- let tint_symbol_1 = S1(2);
- let tint_symbol_2 = S1(3);
- let tint_symbol_3 = array<S1, 3u>(tint_symbol, tint_symbol_1, tint_symbol_2);
- let tint_symbol_4 = S2(tint_symbol_3);
- var x = tint_symbol_4.a[1].a;
-}
-
-struct S2 {
- a : array<S1, 3u>,
-}
-
-struct S1 {
- a : i32,
-}
-)";
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, NoChangeOnVarDecl) {
- auto* src = R"(
-struct S {
- a : i32,
- b : f32,
- c : i32,
-}
-
-fn f() {
- var local_arr = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
- var local_str = S(1, 2.0, 3);
-}
-
-let module_arr : array<f32, 4u> = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
-
-let module_str : S = S(1, 2.0, 3);
-)";
-
- auto* expect = src;
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(PromoteInitializersToConstVarTest, NoChangeOnVarDecl_OutOfOrder) {
- auto* src = R"(
-fn f() {
- var local_arr = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
- var local_str = S(1, 2.0, 3);
-}
-
-let module_str : S = S(1, 2.0, 3);
-
-struct S {
- a : i32,
- b : f32,
- c : i32,
-}
-
-let module_arr : array<f32, 4u> = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
-)";
-
- auto* expect = src;
-
- DataMap data;
- auto got = Run<PromoteInitializersToConstVar>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-} // namespace
-} // namespace tint::transform
diff --git a/src/tint/transform/promote_initializers_to_let.cc b/src/tint/transform/promote_initializers_to_let.cc
new file mode 100644
index 0000000..b57fb25
--- /dev/null
+++ b/src/tint/transform/promote_initializers_to_let.cc
@@ -0,0 +1,106 @@
+// 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/transform/promote_initializers_to_let.h"
+#include "src/tint/program_builder.h"
+#include "src/tint/sem/call.h"
+#include "src/tint/sem/statement.h"
+#include "src/tint/sem/type_constructor.h"
+#include "src/tint/transform/utils/hoist_to_decl_before.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::transform::PromoteInitializersToLet);
+
+namespace tint::transform {
+
+PromoteInitializersToLet::PromoteInitializersToLet() = default;
+
+PromoteInitializersToLet::~PromoteInitializersToLet() = default;
+
+void PromoteInitializersToLet::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+ HoistToDeclBefore hoist_to_decl_before(ctx);
+
+ // Hoists array and structure initializers to a constant variable, declared
+ // just before the statement of usage.
+ auto promote = [&](const sem::Expression* expr) {
+ auto* sem_stmt = expr->Stmt();
+ if (!sem_stmt) {
+ // Expression is outside of a statement. This usually means the
+ // expression is part of a global (module-scope) constant declaration.
+ // These must be constexpr, and so cannot contain the type of
+ // expressions that must be sanitized.
+ return true;
+ }
+
+ auto* stmt = sem_stmt->Declaration();
+
+ if (auto* src_var_decl = stmt->As<ast::VariableDeclStatement>()) {
+ if (src_var_decl->variable->constructor == expr->Declaration()) {
+ // This statement is just a variable declaration with the
+ // initializer as the constructor value. This is what we're
+ // attempting to transform to, and so ignore.
+ return true;
+ }
+ }
+
+ auto* src_ty = expr->Type();
+ if (!src_ty->IsAnyOf<sem::Array, sem::Struct>()) {
+ // We only care about array and struct initializers
+ return true;
+ }
+
+ return hoist_to_decl_before.Add(expr, expr->Declaration(), true);
+ };
+
+ for (auto* node : ctx.src->ASTNodes().Objects()) {
+ bool ok = Switch(
+ node, //
+ [&](const ast::CallExpression* expr) {
+ if (auto* sem = ctx.src->Sem().Get(expr)) {
+ auto* ctor = sem->UnwrapMaterialize()->As<sem::Call>();
+ if (ctor->Target()->Is<sem::TypeConstructor>()) {
+ return promote(sem);
+ }
+ }
+ return true;
+ },
+ [&](const ast::IdentifierExpression* expr) {
+ if (auto* user = ctx.src->Sem().Get<sem::VariableUser>(expr)) {
+ // Identifier resolves to a variable
+ if (auto* stmt = user->Stmt()) {
+ if (auto* decl = stmt->Declaration()->As<ast::VariableDeclStatement>();
+ decl && decl->variable->Is<ast::Const>()) {
+ // The identifier is used on the RHS of a 'const' declaration. Ignore.
+ return true;
+ }
+ }
+ if (user->Variable()->Declaration()->Is<ast::Const>()) {
+ // The identifier resolves to a 'const' variable, but isn't used to
+ // initialize another 'const'. This needs promoting.
+ return promote(user);
+ }
+ }
+ return true;
+ },
+ [&](Default) { return true; });
+
+ if (!ok) {
+ return;
+ }
+ }
+
+ hoist_to_decl_before.Apply();
+ ctx.Clone();
+}
+
+} // namespace tint::transform
diff --git a/src/tint/transform/promote_initializers_to_const_var.h b/src/tint/transform/promote_initializers_to_let.h
similarity index 63%
rename from src/tint/transform/promote_initializers_to_const_var.h
rename to src/tint/transform/promote_initializers_to_let.h
index 67a32c4..41f99d7 100644
--- a/src/tint/transform/promote_initializers_to_const_var.h
+++ b/src/tint/transform/promote_initializers_to_let.h
@@ -12,23 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef SRC_TINT_TRANSFORM_PROMOTE_INITIALIZERS_TO_CONST_VAR_H_
-#define SRC_TINT_TRANSFORM_PROMOTE_INITIALIZERS_TO_CONST_VAR_H_
+#ifndef SRC_TINT_TRANSFORM_PROMOTE_INITIALIZERS_TO_LET_H_
+#define SRC_TINT_TRANSFORM_PROMOTE_INITIALIZERS_TO_LET_H_
#include "src/tint/transform/transform.h"
namespace tint::transform {
-/// A transform that hoists the array and structure initializers to a constant
-/// variable, declared just before the statement of usage.
+/// A transform that hoists array and structure constructors, and identifiers resolving to a
+/// 'const' array to a 'let' variable, declared just before the statement of usage.
+/// This transform is used by backends that do not support expressions that operate on an immediate
+/// array or structure. For example, the following is not immediately expressable for HLSL:
+/// `array<i32, 2>(1, 2)[0]`
/// @see crbug.com/tint/406
-class PromoteInitializersToConstVar : public Castable<PromoteInitializersToConstVar, Transform> {
+class PromoteInitializersToLet : public Castable<PromoteInitializersToLet, Transform> {
public:
/// Constructor
- PromoteInitializersToConstVar();
+ PromoteInitializersToLet();
/// Destructor
- ~PromoteInitializersToConstVar() override;
+ ~PromoteInitializersToLet() override;
protected:
/// Runs the transform using the CloneContext built for transforming a
@@ -42,4 +45,4 @@
} // namespace tint::transform
-#endif // SRC_TINT_TRANSFORM_PROMOTE_INITIALIZERS_TO_CONST_VAR_H_
+#endif // SRC_TINT_TRANSFORM_PROMOTE_INITIALIZERS_TO_LET_H_
diff --git a/src/tint/transform/promote_initializers_to_let_test.cc b/src/tint/transform/promote_initializers_to_let_test.cc
new file mode 100644
index 0000000..d4d9fb2
--- /dev/null
+++ b/src/tint/transform/promote_initializers_to_let_test.cc
@@ -0,0 +1,1225 @@
+// Copyright 2021 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/transform/promote_initializers_to_let.h"
+
+#include "src/tint/transform/test_helper.h"
+
+namespace tint::transform {
+namespace {
+
+using PromoteInitializersToLetTest = TransformTest;
+
+TEST_F(PromoteInitializersToLetTest, EmptyModule) {
+ auto* src = "";
+ auto* expect = "";
+
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, BasicArray) {
+ auto* src = R"(
+fn f() {
+ var f0 = 1.0;
+ var f1 = 2.0;
+ var f2 = 3.0;
+ var f3 = 4.0;
+ var i = array<f32, 4u>(f0, f1, f2, f3)[2];
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var f0 = 1.0;
+ var f1 = 2.0;
+ var f2 = 3.0;
+ var f3 = 4.0;
+ let tint_symbol = array<f32, 4u>(f0, f1, f2, f3);
+ var i = tint_symbol[2];
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, BasicStruct) {
+ auto* src = R"(
+struct S {
+ a : i32,
+ b : f32,
+ c : vec3<f32>,
+};
+
+fn f() {
+ var x = S(1, 2.0, vec3<f32>()).b;
+}
+)";
+
+ auto* expect = R"(
+struct S {
+ a : i32,
+ b : f32,
+ c : vec3<f32>,
+}
+
+fn f() {
+ let tint_symbol = S(1, 2.0, vec3<f32>());
+ var x = tint_symbol.b;
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, BasicStruct_OutOfOrder) {
+ auto* src = R"(
+fn f() {
+ var x = S(1, 2.0, vec3<f32>()).b;
+}
+
+struct S {
+ a : i32,
+ b : f32,
+ c : vec3<f32>,
+};
+)";
+
+ auto* expect = R"(
+fn f() {
+ let tint_symbol = S(1, 2.0, vec3<f32>());
+ var x = tint_symbol.b;
+}
+
+struct S {
+ a : i32,
+ b : f32,
+ c : vec3<f32>,
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, GlobalConstBasicArray) {
+ auto* src = R"(
+const f0 = 1.0;
+
+const f1 = 2.0;
+
+const C = array<f32, 2u>(f0, f1);
+
+fn f() {
+ var f0 = 100.0;
+ var f1 = 100.0;
+ var i = C[1];
+}
+)";
+
+ auto* expect = R"(
+const f0 = 1.0;
+
+const f1 = 2.0;
+
+const C = array<f32, 2u>(f0, f1);
+
+fn f() {
+ var f0 = 100.0;
+ var f1 = 100.0;
+ let tint_symbol = C;
+ var i = tint_symbol[1];
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, GlobalConstBasicArray_OutOfOrder) {
+ auto* src = R"(
+fn f() {
+ var f0 = 100.0;
+ var f1 = 100.0;
+ var i = C[1];
+}
+
+const C = array<f32, 2u>(f0, f1);
+
+const f0 = 1.0;
+
+const f1 = 2.0;
+)";
+
+ auto* expect = R"(
+fn f() {
+ var f0 = 100.0;
+ var f1 = 100.0;
+ let tint_symbol = C;
+ var i = tint_symbol[1];
+}
+
+const C = array<f32, 2u>(f0, f1);
+
+const f0 = 1.0;
+
+const f1 = 2.0;
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, LocalConstBasicArray) {
+ auto* src = R"(
+fn f() {
+ const f0 = 1.0;
+ const f1 = 2.0;
+ const C = array<f32, 2u>(f0, f1);
+ var i = C[1];
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ const f0 = 1.0;
+ const f1 = 2.0;
+ const C = array<f32, 2u>(f0, f1);
+ let tint_symbol = C;
+ var i = tint_symbol[1];
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, ArrayInForLoopInit) {
+ auto* src = R"(
+fn f() {
+ var insert_after = 1;
+ for(var i = array<f32, 4u>(0.0, 1.0, 2.0, 3.0)[2]; ; ) {
+ break;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var insert_after = 1;
+ let tint_symbol = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
+ for(var i = tint_symbol[2]; ; ) {
+ break;
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, LocalConstArrayInForLoopInit) {
+ auto* src = R"(
+fn f() {
+ const arr = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
+ var insert_after = 1;
+ for(var i = arr[2]; ; ) {
+ break;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ const arr = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
+ var insert_after = 1;
+ let tint_symbol = arr;
+ for(var i = tint_symbol[2]; ; ) {
+ break;
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, GlobalConstArrayInForLoopInit) {
+ auto* src = R"(
+const arr = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
+
+fn f() {
+ var insert_after = 1;
+ for(var i = arr[2]; ; ) {
+ break;
+ }
+}
+)";
+
+ auto* expect = R"(
+const arr = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
+
+fn f() {
+ var insert_after = 1;
+ let tint_symbol = arr;
+ for(var i = tint_symbol[2]; ; ) {
+ break;
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, StructInForLoopInit) {
+ auto* src = R"(
+struct S {
+ a : i32,
+ b : f32,
+ c : vec3<f32>,
+};
+
+fn f() {
+ var insert_after = 1;
+ for(var x = S(1, 2.0, vec3<f32>()).b; ; ) {
+ break;
+ }
+}
+)";
+
+ auto* expect = R"(
+struct S {
+ a : i32,
+ b : f32,
+ c : vec3<f32>,
+}
+
+fn f() {
+ var insert_after = 1;
+ let tint_symbol = S(1, 2.0, vec3<f32>());
+ for(var x = tint_symbol.b; ; ) {
+ break;
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, StructInForLoopInit_OutOfOrder) {
+ auto* src = R"(
+fn f() {
+ var insert_after = 1;
+ for(var x = S(1, 2.0, vec3<f32>()).b; ; ) {
+ break;
+ }
+}
+
+struct S {
+ a : i32,
+ b : f32,
+ c : vec3<f32>,
+};
+)";
+
+ auto* expect = R"(
+fn f() {
+ var insert_after = 1;
+ let tint_symbol = S(1, 2.0, vec3<f32>());
+ for(var x = tint_symbol.b; ; ) {
+ break;
+ }
+}
+
+struct S {
+ a : i32,
+ b : f32,
+ c : vec3<f32>,
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, ArrayInForLoopCond) {
+ auto* src = R"(
+fn f() {
+ var f = 1.0;
+ for(; f == array<f32, 1u>(f)[0]; f = f + 1.0) {
+ var marker = 1;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var f = 1.0;
+ loop {
+ let tint_symbol = array<f32, 1u>(f);
+ if (!((f == tint_symbol[0]))) {
+ break;
+ }
+ {
+ var marker = 1;
+ }
+
+ continuing {
+ f = (f + 1.0);
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, LocalConstArrayInForLoopCond) {
+ auto* src = R"(
+fn f() {
+ const f = 1.0;
+ const arr = array<f32, 1u>(f);
+ for(var i = f; i == arr[0]; i = i + 1.0) {
+ var marker = 1;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ const f = 1.0;
+ const arr = array<f32, 1u>(f);
+ {
+ var i = f;
+ loop {
+ let tint_symbol = arr;
+ if (!((i == tint_symbol[0]))) {
+ break;
+ }
+ {
+ var marker = 1;
+ }
+
+ continuing {
+ i = (i + 1.0);
+ }
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, GlobalConstArrayInForLoopCond) {
+ auto* src = R"(
+const f = 1.0;
+
+const arr = array<f32, 1u>(f);
+
+fn F() {
+ for(var i = f; i == arr[0]; i = i + 1.0) {
+ var marker = 1;
+ }
+}
+)";
+
+ auto* expect = R"(
+const f = 1.0;
+
+const arr = array<f32, 1u>(f);
+
+fn F() {
+ {
+ var i = f;
+ loop {
+ let tint_symbol = arr;
+ if (!((i == tint_symbol[0]))) {
+ break;
+ }
+ {
+ var marker = 1;
+ }
+
+ continuing {
+ i = (i + 1.0);
+ }
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, ArrayInForLoopCont) {
+ auto* src = R"(
+fn f() {
+ var f = 0.0;
+ for(; f < 10.0; f = f + array<f32, 1u>(1.0)[0]) {
+ var marker = 1;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var f = 0.0;
+ loop {
+ if (!((f < 10.0))) {
+ break;
+ }
+ {
+ var marker = 1;
+ }
+
+ continuing {
+ let tint_symbol = array<f32, 1u>(1.0);
+ f = (f + tint_symbol[0]);
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, LocalConstArrayInForLoopCont) {
+ auto* src = R"(
+fn f() {
+ const arr = array<f32, 1u>(1.0);
+ var f = 0.0;
+ for(; f < 10.0; f = f + arr[0]) {
+ var marker = 1;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ const arr = array<f32, 1u>(1.0);
+ var f = 0.0;
+ loop {
+ if (!((f < 10.0))) {
+ break;
+ }
+ {
+ var marker = 1;
+ }
+
+ continuing {
+ let tint_symbol = arr;
+ f = (f + tint_symbol[0]);
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, GlobalConstArrayInForLoopCont) {
+ auto* src = R"(
+const arr = array<f32, 1u>(1.0);
+
+fn f() {
+ var f = 0.0;
+ for(; f < 10.0; f = f + arr[0]) {
+ var marker = 1;
+ }
+}
+)";
+
+ auto* expect = R"(
+const arr = array<f32, 1u>(1.0);
+
+fn f() {
+ var f = 0.0;
+ loop {
+ if (!((f < 10.0))) {
+ break;
+ }
+ {
+ var marker = 1;
+ }
+
+ continuing {
+ let tint_symbol = arr;
+ f = (f + tint_symbol[0]);
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, ArrayInForLoopInitCondCont) {
+ auto* src = R"(
+fn f() {
+ for(var f = array<f32, 1u>(0.0)[0];
+ f < array<f32, 1u>(1.0)[0];
+ f = f + array<f32, 1u>(2.0)[0]) {
+ var marker = 1;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ let tint_symbol = array<f32, 1u>(0.0);
+ {
+ var f = tint_symbol[0];
+ loop {
+ let tint_symbol_1 = array<f32, 1u>(1.0);
+ if (!((f < tint_symbol_1[0]))) {
+ break;
+ }
+ {
+ var marker = 1;
+ }
+
+ continuing {
+ let tint_symbol_2 = array<f32, 1u>(2.0);
+ f = (f + tint_symbol_2[0]);
+ }
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, LocalConstArrayInForLoopInitCondCont) {
+ auto* src = R"(
+fn f() {
+ const arr_a = array<f32, 1u>(0.0);
+ const arr_b = array<f32, 1u>(1.0);
+ const arr_c = array<f32, 1u>(2.0);
+ for(var f = arr_a[0]; f < arr_b[0]; f = f + arr_c[0]) {
+ var marker = 1;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ const arr_a = array<f32, 1u>(0.0);
+ const arr_b = array<f32, 1u>(1.0);
+ const arr_c = array<f32, 1u>(2.0);
+ let tint_symbol = arr_a;
+ {
+ var f = tint_symbol[0];
+ loop {
+ let tint_symbol_1 = arr_b;
+ if (!((f < tint_symbol_1[0]))) {
+ break;
+ }
+ {
+ var marker = 1;
+ }
+
+ continuing {
+ let tint_symbol_2 = arr_c;
+ f = (f + tint_symbol_2[0]);
+ }
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, ArrayInElseIf) {
+ auto* src = R"(
+fn f() {
+ var f = 1.0;
+ if (true) {
+ var marker = 0;
+ } else if (f == array<f32, 2u>(f, f)[0]) {
+ var marker = 1;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var f = 1.0;
+ if (true) {
+ var marker = 0;
+ } else {
+ let tint_symbol = array<f32, 2u>(f, f);
+ if ((f == tint_symbol[0])) {
+ var marker = 1;
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, ArrayInElseIfChain) {
+ auto* src = R"(
+fn f() {
+ var f = 1.0;
+ if (true) {
+ var marker = 0;
+ } else if (true) {
+ var marker = 1;
+ } else if (f == array<f32, 2u>(f, f)[0]) {
+ var marker = 2;
+ } else if (f == array<f32, 2u>(f, f)[1]) {
+ var marker = 3;
+ } else if (true) {
+ var marker = 4;
+ } else {
+ var marker = 5;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var f = 1.0;
+ if (true) {
+ var marker = 0;
+ } else if (true) {
+ var marker = 1;
+ } else {
+ let tint_symbol = array<f32, 2u>(f, f);
+ if ((f == tint_symbol[0])) {
+ var marker = 2;
+ } else {
+ let tint_symbol_1 = array<f32, 2u>(f, f);
+ if ((f == tint_symbol_1[1])) {
+ var marker = 3;
+ } else if (true) {
+ var marker = 4;
+ } else {
+ var marker = 5;
+ }
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, LocalConstArrayInElseIfChain) {
+ auto* src = R"(
+fn f() {
+ const f = 1.0;
+ const arr = array<f32, 2u>(f, f);
+ if (true) {
+ var marker = 0;
+ } else if (true) {
+ var marker = 1;
+ } else if (f == arr[0]) {
+ var marker = 2;
+ } else if (f == arr[1]) {
+ var marker = 3;
+ } else if (true) {
+ var marker = 4;
+ } else {
+ var marker = 5;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ const f = 1.0;
+ const arr = array<f32, 2u>(f, f);
+ if (true) {
+ var marker = 0;
+ } else if (true) {
+ var marker = 1;
+ } else {
+ let tint_symbol = arr;
+ if ((f == tint_symbol[0])) {
+ var marker = 2;
+ } else {
+ let tint_symbol_1 = arr;
+ if ((f == tint_symbol_1[1])) {
+ var marker = 3;
+ } else if (true) {
+ var marker = 4;
+ } else {
+ var marker = 5;
+ }
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, GlobalConstArrayInElseIfChain) {
+ auto* src = R"(
+const f = 1.0;
+
+const arr = array<f32, 2u>(f, f);
+
+fn F() {
+ if (true) {
+ var marker = 0;
+ } else if (true) {
+ var marker = 1;
+ } else if (f == arr[0]) {
+ var marker = 2;
+ } else if (f == arr[1]) {
+ var marker = 3;
+ } else if (true) {
+ var marker = 4;
+ } else {
+ var marker = 5;
+ }
+}
+)";
+
+ auto* expect = R"(
+const f = 1.0;
+
+const arr = array<f32, 2u>(f, f);
+
+fn F() {
+ if (true) {
+ var marker = 0;
+ } else if (true) {
+ var marker = 1;
+ } else {
+ let tint_symbol = arr;
+ if ((f == tint_symbol[0])) {
+ var marker = 2;
+ } else {
+ let tint_symbol_1 = arr;
+ if ((f == tint_symbol_1[1])) {
+ var marker = 3;
+ } else if (true) {
+ var marker = 4;
+ } else {
+ var marker = 5;
+ }
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, ArrayInArrayArray) {
+ auto* src = R"(
+fn f() {
+ var i = array<array<f32, 2u>, 2u>(array<f32, 2u>(1.0, 2.0), array<f32, 2u>(3.0, 4.0))[0][1];
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ let tint_symbol = array<f32, 2u>(1.0, 2.0);
+ let tint_symbol_1 = array<f32, 2u>(3.0, 4.0);
+ let tint_symbol_2 = array<array<f32, 2u>, 2u>(tint_symbol, tint_symbol_1);
+ var i = tint_symbol_2[0][1];
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, LocalConstArrayInArrayArray) {
+ auto* src = R"(
+fn f() {
+ const arr_0 = array<f32, 2u>(1.0, 2.0);
+ const arr_1 = array<f32, 2u>(3.0, 4.0);
+ const arr_2 = array<array<f32, 2u>, 2u>(arr_0, arr_1);
+ var i = arr_2[0][1];
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ const arr_0 = array<f32, 2u>(1.0, 2.0);
+ const arr_1 = array<f32, 2u>(3.0, 4.0);
+ const arr_2 = array<array<f32, 2u>, 2u>(arr_0, arr_1);
+ let tint_symbol = arr_2;
+ var i = tint_symbol[0][1];
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, GlobalConstArrayInArrayArray) {
+ auto* src = R"(
+const arr_0 = array<f32, 2u>(1.0, 2.0);
+
+const arr_1 = array<f32, 2u>(3.0, 4.0);
+
+const arr_2 = array<array<f32, 2u>, 2u>(arr_0, arr_1);
+
+fn f() {
+ var i = arr_2[0][1];
+}
+)";
+
+ auto* expect = R"(
+const arr_0 = array<f32, 2u>(1.0, 2.0);
+
+const arr_1 = array<f32, 2u>(3.0, 4.0);
+
+const arr_2 = array<array<f32, 2u>, 2u>(arr_0, arr_1);
+
+fn f() {
+ let tint_symbol = arr_2;
+ var i = tint_symbol[0][1];
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, StructNested) {
+ auto* src = R"(
+struct S1 {
+ a : i32,
+};
+
+struct S2 {
+ a : i32,
+ b : S1,
+ c : i32,
+};
+
+struct S3 {
+ a : S2,
+};
+
+fn f() {
+ var x = S3(S2(1, S1(2), 3)).a.b.a;
+}
+)";
+
+ auto* expect = R"(
+struct S1 {
+ a : i32,
+}
+
+struct S2 {
+ a : i32,
+ b : S1,
+ c : i32,
+}
+
+struct S3 {
+ a : S2,
+}
+
+fn f() {
+ let tint_symbol = S1(2);
+ let tint_symbol_1 = S2(1, tint_symbol, 3);
+ let tint_symbol_2 = S3(tint_symbol_1);
+ var x = tint_symbol_2.a.b.a;
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, Mixed) {
+ auto* src = R"(
+struct S1 {
+ a : i32,
+};
+
+struct S2 {
+ a : array<S1, 3u>,
+};
+
+fn f() {
+ var x = S2(array<S1, 3u>(S1(1), S1(2), S1(3))).a[1].a;
+}
+)";
+
+ auto* expect = R"(
+struct S1 {
+ a : i32,
+}
+
+struct S2 {
+ a : array<S1, 3u>,
+}
+
+fn f() {
+ let tint_symbol = S1(1);
+ let tint_symbol_1 = S1(2);
+ let tint_symbol_2 = S1(3);
+ let tint_symbol_3 = array<S1, 3u>(tint_symbol, tint_symbol_1, tint_symbol_2);
+ let tint_symbol_4 = S2(tint_symbol_3);
+ var x = tint_symbol_4.a[1].a;
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, Mixed_OutOfOrder) {
+ auto* src = R"(
+fn f() {
+ var x = S2(array<S1, 3u>(S1(1), S1(2), S1(3))).a[1].a;
+}
+
+struct S2 {
+ a : array<S1, 3u>,
+};
+
+struct S1 {
+ a : i32,
+};
+)";
+
+ auto* expect = R"(
+fn f() {
+ let tint_symbol = S1(1);
+ let tint_symbol_1 = S1(2);
+ let tint_symbol_2 = S1(3);
+ let tint_symbol_3 = array<S1, 3u>(tint_symbol, tint_symbol_1, tint_symbol_2);
+ let tint_symbol_4 = S2(tint_symbol_3);
+ var x = tint_symbol_4.a[1].a;
+}
+
+struct S2 {
+ a : array<S1, 3u>,
+}
+
+struct S1 {
+ a : i32,
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, NoChangeOnVarDecl) {
+ auto* src = R"(
+type F = f32;
+
+fn f() {
+ var local_arr = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
+ var local_str = F(3.0);
+}
+
+const module_arr : array<f32, 4u> = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
+
+const module_str : F = F(2.0);
+)";
+
+ auto* expect = src;
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, NoChangeOnVarDecl_OutOfOrder) {
+ auto* src = R"(
+fn f() {
+ var local_arr = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
+ var local_str = F(3.0);
+}
+
+const module_str : F = F(2.0);
+
+type F = f32;
+
+const module_arr : array<f32, 4u> = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
+)";
+
+ auto* expect = src;
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PromoteInitializersToLetTest, ForLoopShadowing) {
+ auto* src = R"(
+fn X() {
+ var i = 10;
+ for(var f = 0; f < 10; f = f + array<i32, 1u>(i)[0]) {
+ var i = 20;
+ }
+}
+
+fn Y() {
+ var i = 10;
+ for(var f = 0; f < array<i32, 1u>(i)[0]; f = f + 1) {
+ var i = 20;
+ }
+}
+
+fn Z() {
+ var i = 10;
+ for(var f = array<i32, 1u>(i)[0]; f < 10; f = f + 1) {
+ var i = 20;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn X() {
+ var i = 10;
+ {
+ var f = 0;
+ loop {
+ if (!((f < 10))) {
+ break;
+ }
+ {
+ var i = 20;
+ }
+
+ continuing {
+ let tint_symbol = array<i32, 1u>(i);
+ f = (f + tint_symbol[0]);
+ }
+ }
+ }
+}
+
+fn Y() {
+ var i = 10;
+ {
+ var f = 0;
+ loop {
+ let tint_symbol_1 = array<i32, 1u>(i);
+ if (!((f < tint_symbol_1[0]))) {
+ break;
+ }
+ {
+ var i = 20;
+ }
+
+ continuing {
+ f = (f + 1);
+ }
+ }
+ }
+}
+
+fn Z() {
+ var i = 10;
+ let tint_symbol_2 = array<i32, 1u>(i);
+ for(var f = tint_symbol_2[0]; (f < 10); f = (f + 1)) {
+ var i = 20;
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<PromoteInitializersToLet>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace
+} // 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 d527a4c..7551c23 100644
--- a/src/tint/transform/promote_side_effects_to_decl.cc
+++ b/src/tint/transform/promote_side_effects_to_decl.cc
@@ -275,7 +275,7 @@
if (auto* sem_e = sem.Get(e)) {
if (auto* var_user = sem_e->As<sem::VariableUser>()) {
// Don't hoist constants.
- if (var_user->ConstantValue().IsValid()) {
+ if (var_user->ConstantValue()) {
return false;
}
// Don't hoist read-only variables as they cannot receive
diff --git a/src/tint/transform/robustness.cc b/src/tint/transform/robustness.cc
index aab1e0c..beb1108 100644
--- a/src/tint/transform/robustness.cc
+++ b/src/tint/transform/robustness.cc
@@ -120,17 +120,18 @@
return nullptr;
}
- if (auto idx_constant = idx_sem->ConstantValue()) {
+ if (auto* idx_constant = idx_sem->ConstantValue()) {
// Constant value index
- if (idx_constant.Type()->Is<sem::I32>()) {
- idx.i32 = static_cast<int32_t>(idx_constant.Element<AInt>(0).value);
+ auto val = std::get<AInt>(idx_constant->Value());
+ if (idx_constant->Type()->Is<sem::I32>()) {
+ idx.i32 = static_cast<int32_t>(val);
idx.is_signed = true;
- } else if (idx_constant.Type()->Is<sem::U32>()) {
- idx.u32 = static_cast<uint32_t>(idx_constant.Element<AInt>(0).value);
+ } else if (idx_constant->Type()->Is<sem::U32>()) {
+ idx.u32 = static_cast<uint32_t>(val);
idx.is_signed = false;
} else {
TINT_ICE(Transform, b.Diagnostics()) << "unsupported constant value for accessor "
- << idx_constant.Type()->TypeInfo().name;
+ << idx_constant->Type()->TypeInfo().name;
return nullptr;
}
} else {
@@ -223,9 +224,9 @@
auto array_idx = signature.IndexOf(sem::ParameterUsage::kArrayIndex);
auto level_idx = signature.IndexOf(sem::ParameterUsage::kLevel);
- auto* texture_arg = expr->args[texture_idx];
- auto* coords_arg = expr->args[coords_idx];
- auto* coords_ty = builtin->Parameters()[coords_idx]->Type();
+ auto* texture_arg = expr->args[static_cast<size_t>(texture_idx)];
+ auto* coords_arg = expr->args[static_cast<size_t>(coords_idx)];
+ auto* coords_ty = builtin->Parameters()[static_cast<size_t>(coords_idx)]->Type();
// If the level is provided, then we need to clamp this. As the level is
// used by textureDimensions() and the texture[Load|Store]() calls, we need
@@ -235,7 +236,7 @@
std::function<const ast::Expression*()> level_arg;
if (level_idx >= 0) {
level_arg = [&] {
- auto* arg = expr->args[level_idx];
+ auto* arg = expr->args[static_cast<size_t>(level_idx)];
auto* num_levels = b.Call("textureNumLevels", ctx.Clone(texture_arg));
auto* zero = b.Expr(0_i);
auto* max = ctx.dst->Sub(num_levels, 1_i);
@@ -258,7 +259,7 @@
// Clamp the array_index argument, if provided
if (array_idx >= 0) {
- auto* arg = expr->args[array_idx];
+ auto* arg = expr->args[static_cast<size_t>(array_idx)];
auto* num_layers = b.Call("textureNumLayers", ctx.Clone(texture_arg));
auto* zero = b.Expr(0_i);
auto* max = ctx.dst->Sub(num_layers, 1_i);
@@ -268,7 +269,7 @@
// Clamp the level argument, if provided
if (level_idx >= 0) {
- auto* arg = expr->args[level_idx];
+ auto* arg = expr->args[static_cast<size_t>(level_idx)];
ctx.Replace(arg, level_arg ? level_arg() : ctx.dst->Expr(0_i));
}
diff --git a/src/tint/transform/robustness_test.cc b/src/tint/transform/robustness_test.cc
index fb0e5a4..8dab595 100644
--- a/src/tint/transform/robustness_test.cc
+++ b/src/tint/transform/robustness_test.cc
@@ -21,7 +21,7 @@
using RobustnessTest = TransformTest;
-TEST_F(RobustnessTest, Array_Idx_Clamp) {
+TEST_F(RobustnessTest, Array_Let_Idx_Clamp) {
auto* src = R"(
var<private> a : array<f32, 3>;
@@ -35,7 +35,7 @@
auto* expect = R"(
var<private> a : array<f32, 3>;
-let c : u32 = 1u;
+const c : u32 = 1u;
fn f() {
let b : f32 = a[1u];
@@ -47,7 +47,33 @@
EXPECT_EQ(expect, str(got));
}
-TEST_F(RobustnessTest, Array_Idx_Clamp_OutOfOrder) {
+TEST_F(RobustnessTest, Array_Const_Idx_Clamp) {
+ auto* src = R"(
+var<private> a : array<f32, 3>;
+
+const c : u32 = 1u;
+
+fn f() {
+ let b : f32 = a[c];
+}
+)";
+
+ auto* expect = R"(
+var<private> a : array<f32, 3>;
+
+const c : u32 = 1u;
+
+fn f() {
+ let b : f32 = a[1u];
+}
+)";
+
+ auto got = Run<Robustness>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(RobustnessTest, Array_Let_Idx_Clamp_OutOfOrder) {
auto* src = R"(
fn f() {
let b : f32 = a[c];
@@ -63,7 +89,33 @@
let b : f32 = a[1u];
}
-let c : u32 = 1u;
+const c : u32 = 1u;
+
+var<private> a : array<f32, 3>;
+)";
+
+ auto got = Run<Robustness>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(RobustnessTest, Array_Const_Idx_Clamp_OutOfOrder) {
+ auto* src = R"(
+fn f() {
+ let b : f32 = a[c];
+}
+
+const c : u32 = 1u;
+
+var<private> a : array<f32, 3>;
+)";
+
+ auto* expect = R"(
+fn f() {
+ let b : f32 = a[1u];
+}
+
+const c : u32 = 1u;
var<private> a : array<f32, 3>;
)";
@@ -1392,7 +1444,7 @@
@group(0) @binding(0) var<storage, read> s : S;
-let c : u32 = 1u;
+const c : u32 = 1u;
fn f() {
let b : f32 = s.b[c];
@@ -1409,7 +1461,7 @@
@group(0) @binding(0) var<storage, read> s : S;
-let c : u32 = 1u;
+const c : u32 = 1u;
fn f() {
let b : f32 = s.b[min(1u, (arrayLength(&(s.b)) - 1u))];
diff --git a/src/tint/transform/single_entry_point_test.cc b/src/tint/transform/single_entry_point_test.cc
index 8445f61..020bd65 100644
--- a/src/tint/transform/single_entry_point_test.cc
+++ b/src/tint/transform/single_entry_point_test.cc
@@ -186,13 +186,13 @@
TEST_F(SingleEntryPointTest, GlobalConstants) {
auto* src = R"(
-let a : f32 = 1.0;
+const a : f32 = 1.0;
-let b : f32 = 1.0;
+const b : f32 = 1.0;
-let c : f32 = 1.0;
+const c : f32 = 1.0;
-let d : f32 = 1.0;
+const d : f32 = 1.0;
@vertex
fn vert_main() -> @builtin(position) vec4<f32> {
@@ -217,7 +217,7 @@
)";
auto* expect = R"(
-let c : f32 = 1.0;
+const c : f32 = 1.0;
@compute @workgroup_size(1)
fn comp_main1() {
@@ -243,6 +243,32 @@
}
)";
+ auto* expect = R"(
+const size : i32 = 1;
+
+@compute @workgroup_size(size)
+fn main() {
+}
+)";
+
+ SingleEntryPoint::Config cfg("main");
+
+ DataMap data;
+ data.Add<SingleEntryPoint::Config>(cfg);
+ auto got = Run<SingleEntryPoint>(src, data);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SingleEntryPointTest, WorkgroupSizeConstPreserved) {
+ auto* src = R"(
+const size : i32 = 1;
+
+@compute @workgroup_size(size)
+fn main() {
+}
+)";
+
auto* expect = src;
SingleEntryPoint::Config cfg("main");
diff --git a/src/tint/transform/spirv_atomic.cc b/src/tint/transform/spirv_atomic.cc
new file mode 100644
index 0000000..dc5b35c
--- /dev/null
+++ b/src/tint/transform/spirv_atomic.cc
@@ -0,0 +1,299 @@
+// 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/transform/spirv_atomic.h"
+
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+#include "src/tint/program_builder.h"
+#include "src/tint/sem/block_statement.h"
+#include "src/tint/sem/function.h"
+#include "src/tint/sem/index_accessor_expression.h"
+#include "src/tint/sem/member_accessor_expression.h"
+#include "src/tint/sem/reference.h"
+#include "src/tint/sem/statement.h"
+#include "src/tint/utils/map.h"
+#include "src/tint/utils/unique_vector.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::transform::SpirvAtomic);
+TINT_INSTANTIATE_TYPEINFO(tint::transform::SpirvAtomic::Stub);
+
+namespace tint::transform {
+
+/// Private implementation of transform
+struct SpirvAtomic::State {
+ private:
+ /// A struct that has been forked because a subset of members were made atomic.
+ struct ForkedStruct {
+ Symbol name;
+ std::unordered_set<size_t> atomic_members;
+ };
+
+ CloneContext& ctx;
+ ProgramBuilder& b = *ctx.dst;
+ std::unordered_map<const ast::Struct*, ForkedStruct> forked_structs;
+ std::unordered_set<const sem::Variable*> atomic_variables;
+ utils::UniqueVector<const sem::Expression*> atomic_expressions;
+
+ public:
+ /// Constructor
+ /// @param c the clone context
+ explicit State(CloneContext& c) : ctx(c) {}
+
+ /// Runs the transform
+ void 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()) {
+ if (auto* stub = ast::GetAttribute<Stub>(fn->attributes)) {
+ auto* sem = ctx.src->Sem().Get(fn);
+
+ for (auto* call : sem->CallSites()) {
+ // The first argument is always the atomic.
+ // The stub passes this by value, whereas the builtin wants a pointer.
+ // Take the address of the atomic argument.
+ auto& args = call->Declaration()->args;
+ auto out_args = ctx.Clone(args);
+ out_args[0] = b.AddressOf(out_args[0]);
+
+ // Replace all callsites of this stub to a call to the real builtin
+ if (stub->builtin == sem::BuiltinType::kAtomicCompareExchangeWeak) {
+ // atomicCompareExchangeWeak returns a struct, so insert a call to it above
+ // the current statement, and replace the current call with the struct's
+ // `old_value` member.
+ auto* block = call->Stmt()->Block()->Declaration();
+ auto old_value = b.Symbols().New("old_value");
+ auto old_value_decl = b.Decl(b.Let(
+ old_value, nullptr,
+ b.MemberAccessor(b.Call(sem::str(stub->builtin), std::move(out_args)),
+ b.Expr("old_value"))));
+ ctx.InsertBefore(block->statements, call->Stmt()->Declaration(),
+ old_value_decl);
+ ctx.Replace(call->Declaration(), b.Expr(old_value));
+ } else {
+ ctx.Replace(call->Declaration(),
+ b.Call(sem::str(stub->builtin), std::move(out_args)));
+ }
+
+ // Keep track of this expression. We'll need to modify the source variable /
+ // structure to be atomic.
+ atomic_expressions.add(ctx.src->Sem().Get(args[0]));
+ }
+
+ // Remove the stub from the output program
+ ctx.Remove(ctx.src->AST().GlobalDeclarations(), fn);
+ }
+ }
+
+ // Transform all variables and structure members that were used in atomic operations as
+ // atomic types. This propagates up originating expression chains.
+ ProcessAtomicExpressions();
+
+ // If we need to change structure members, then fork them.
+ if (!forked_structs.empty()) {
+ ctx.ReplaceAll([&](const ast::Struct* str) {
+ // Always emit the original structure. This allows unrelated usage of the structure
+ // to continue working.
+ // auto* original = ctx.CloneWithoutTransform(str);
+
+ // Is `str` a structure we need to fork?
+ if (auto it = forked_structs.find(str); it != forked_structs.end()) {
+ const auto& forked = it->second;
+
+ // Re-create the structure swapping in the atomic-flavoured members
+ std::vector<const ast::StructMember*> members(str->members.size());
+ for (size_t i = 0; i < str->members.size(); i++) {
+ auto* member = str->members[i];
+ if (forked.atomic_members.count(i)) {
+ auto* type = AtomicTypeFor(ctx.src->Sem().Get(member)->Type());
+ auto name = ctx.src->Symbols().NameFor(member->symbol);
+ members[i] = b.Member(name, type, ctx.Clone(member->attributes));
+ } else {
+ members[i] = ctx.Clone(member);
+ }
+ }
+ b.Structure(forked.name, std::move(members));
+ }
+
+ // return original;
+ return nullptr;
+ });
+ }
+
+ // Replace assignments and decls from atomic variables with atomicLoads, and assignments to
+ // atomic variables with atomicStores.
+ ReplaceLoadsAndStores();
+
+ ctx.Clone();
+ }
+
+ private:
+ ForkedStruct& Fork(const ast::Struct* str) {
+ auto& forked = forked_structs[str];
+ if (!forked.name.IsValid()) {
+ forked.name = b.Symbols().New(ctx.src->Symbols().NameFor(str->name) + "_atomic");
+ }
+ return forked;
+ }
+
+ void ProcessAtomicExpressions() {
+ for (size_t i = 0; i < atomic_expressions.size(); i++) {
+ Switch(
+ atomic_expressions[i], //
+ [&](const sem::VariableUser* user) {
+ auto* v = user->Variable()->Declaration();
+ if (v->type && atomic_variables.emplace(user->Variable()).second) {
+ ctx.Replace(v->type, AtomicTypeFor(user->Variable()->Type()));
+ }
+ if (auto* ctor = user->Variable()->Constructor()) {
+ atomic_expressions.add(ctor);
+ }
+ },
+ [&](const sem::StructMemberAccess* access) {
+ // Fork the struct (the first time) and mark member(s) that need to be made
+ // atomic.
+ auto* member = access->Member();
+ Fork(member->Struct()->Declaration()).atomic_members.emplace(member->Index());
+ atomic_expressions.add(access->Object());
+ },
+ [&](const sem::IndexAccessorExpression* index) {
+ atomic_expressions.add(index->Object());
+ },
+ [&](const sem::Expression* e) {
+ if (auto* unary = e->Declaration()->As<ast::UnaryOpExpression>()) {
+ atomic_expressions.add(ctx.src->Sem().Get(unary->expr));
+ }
+ });
+ }
+ }
+
+ const ast::Type* AtomicTypeFor(const sem::Type* ty) {
+ return Switch(
+ ty, //
+ [&](const sem::I32*) { return b.ty.atomic(CreateASTTypeFor(ctx, ty)); },
+ [&](const sem::U32*) { return b.ty.atomic(CreateASTTypeFor(ctx, ty)); },
+ [&](const sem::Struct* str) { return b.ty.type_name(Fork(str->Declaration()).name); },
+ [&](const sem::Array* arr) {
+ return arr->IsRuntimeSized()
+ ? b.ty.array(AtomicTypeFor(arr->ElemType()))
+ : b.ty.array(AtomicTypeFor(arr->ElemType()), u32(arr->Count()));
+ },
+ [&](const sem::Pointer* ptr) {
+ return b.ty.pointer(AtomicTypeFor(ptr->StoreType()), ptr->StorageClass(),
+ ptr->Access());
+ },
+ [&](const sem::Reference* ref) { return AtomicTypeFor(ref->StoreType()); },
+ [&](Default) {
+ TINT_ICE(Transform, b.Diagnostics())
+ << "unhandled type: " << ty->FriendlyName(ctx.src->Symbols());
+ return nullptr;
+ });
+ }
+
+ void ReplaceLoadsAndStores() {
+ // Returns true if 'e' is a reference to an atomic variable or struct member
+ auto is_ref_to_atomic_var = [&](const sem::Expression* e) {
+ if (tint::Is<sem::Reference>(e->Type()) && e->SourceVariable() &&
+ (atomic_variables.count(e->SourceVariable()) != 0)) {
+ // If it's a struct member, make sure it's one we marked as atomic
+ if (auto* ma = e->As<sem::StructMemberAccess>()) {
+ auto it = forked_structs.find(ma->Member()->Struct()->Declaration());
+ if (it != forked_structs.end()) {
+ auto& forked = it->second;
+ return forked.atomic_members.count(ma->Member()->Index()) != 0;
+ }
+ }
+ return true;
+ }
+ return false;
+ };
+
+ // Look for loads and stores via assignments and decls of atomic variables we've collected
+ // so far, and replace them with atomicLoad and atomicStore.
+ for (auto* atomic_var : atomic_variables) {
+ for (auto* vu : atomic_var->Users()) {
+ Switch(
+ vu->Stmt()->Declaration(),
+ [&](const ast::AssignmentStatement* assign) {
+ auto* sem_lhs = ctx.src->Sem().Get(assign->lhs);
+ if (is_ref_to_atomic_var(sem_lhs)) {
+ ctx.Replace(assign, [=] {
+ auto* lhs = ctx.CloneWithoutTransform(assign->lhs);
+ auto* rhs = ctx.CloneWithoutTransform(assign->rhs);
+ auto* call = b.Call(sem::str(sem::BuiltinType::kAtomicStore),
+ b.AddressOf(lhs), rhs);
+ return b.CallStmt(call);
+ });
+ return;
+ }
+
+ auto sem_rhs = ctx.src->Sem().Get(assign->rhs);
+ if (is_ref_to_atomic_var(sem_rhs)) {
+ ctx.Replace(assign->rhs, [=] {
+ auto* rhs = ctx.CloneWithoutTransform(assign->rhs);
+ return b.Call(sem::str(sem::BuiltinType::kAtomicLoad),
+ b.AddressOf(rhs));
+ });
+ return;
+ }
+ },
+ [&](const ast::VariableDeclStatement* decl) {
+ auto* var = decl->variable;
+ if (auto* sem_ctor = ctx.src->Sem().Get(var->constructor)) {
+ if (is_ref_to_atomic_var(sem_ctor)) {
+ ctx.Replace(var->constructor, [=] {
+ auto* rhs = ctx.CloneWithoutTransform(var->constructor);
+ return b.Call(sem::str(sem::BuiltinType::kAtomicLoad),
+ b.AddressOf(rhs));
+ });
+ return;
+ }
+ }
+ });
+ }
+ }
+ }
+};
+
+SpirvAtomic::SpirvAtomic() = default;
+SpirvAtomic::~SpirvAtomic() = default;
+
+SpirvAtomic::Stub::Stub(ProgramID pid, sem::BuiltinType b) : Base(pid), builtin(b) {}
+SpirvAtomic::Stub::~Stub() = default;
+std::string SpirvAtomic::Stub::InternalName() const {
+ return "@internal(spirv-atomic " + std::string(sem::str(builtin)) + ")";
+}
+
+const SpirvAtomic::Stub* SpirvAtomic::Stub::Clone(CloneContext* ctx) const {
+ return ctx->dst->ASTNodes().Create<SpirvAtomic::Stub>(ctx->dst->ID(), 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();
+}
+
+} // namespace tint::transform
diff --git a/src/tint/transform/spirv_atomic.h b/src/tint/transform/spirv_atomic.h
new file mode 100644
index 0000000..36ac842
--- /dev/null
+++ b/src/tint/transform/spirv_atomic.h
@@ -0,0 +1,84 @@
+// 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_TRANSFORM_SPIRV_ATOMIC_H_
+#define SRC_TINT_TRANSFORM_SPIRV_ATOMIC_H_
+
+#include <string>
+
+#include "src/tint/ast/internal_attribute.h"
+#include "src/tint/sem/builtin_type.h"
+#include "src/tint/transform/transform.h"
+
+// Forward declarations
+namespace tint {
+class CloneContext;
+} // namespace tint
+
+namespace tint::transform {
+
+/// SpirvAtomic is a transform that replaces calls to stub functions created by the SPIR-V reader
+/// with calls to the WGSL atomic builtin. It also makes sure to replace variable declarations that
+/// are the target of the atomic operations with an atomic declaration of the same type. For
+/// structs, it creates a copy of the original struct with atomic members.
+class SpirvAtomic final : public Castable<SpirvAtomic, Transform> {
+ public:
+ /// Constructor
+ SpirvAtomic();
+ /// Destructor
+ ~SpirvAtomic() override;
+
+ /// Stub is an attribute applied to stub SPIR-V reader generated functions that need to be
+ /// translated to an atomic builtin.
+ class Stub final : public Castable<Stub, ast::InternalAttribute> {
+ public:
+ /// @param program_id the identifier of the program that owns this node
+ /// @param builtin the atomic builtin this stub represents
+ Stub(ProgramID program_id, sem::BuiltinType builtin);
+ /// Destructor
+ ~Stub() override;
+
+ /// @return a short description of the internal attribute which will be
+ /// displayed as `@internal(<name>)`
+ std::string InternalName() const override;
+
+ /// Performs a deep clone of this object using the CloneContext `ctx`.
+ /// @param ctx the clone context
+ /// @return the newly cloned object
+ const Stub* Clone(CloneContext* ctx) const override;
+
+ /// The type of the intrinsic
+ 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;
+
+ protected:
+ 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
+
+#endif // SRC_TINT_TRANSFORM_SPIRV_ATOMIC_H_
diff --git a/src/tint/transform/spirv_atomic_test.cc b/src/tint/transform/spirv_atomic_test.cc
new file mode 100644
index 0000000..7f07d06
--- /dev/null
+++ b/src/tint/transform/spirv_atomic_test.cc
@@ -0,0 +1,1383 @@
+// 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/transform/spirv_atomic.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "src/tint/reader/wgsl/parser_impl.h"
+#include "src/tint/transform/test_helper.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::transform {
+namespace {
+
+class SpirvAtomicTest : public TransformTest {
+ public:
+ Output Run(std::string in) {
+ auto file = std::make_unique<Source::File>("test", std::move(in));
+ auto parser = reader::wgsl::ParserImpl(file.get());
+ parser.Parse();
+
+ auto& b = parser.builder();
+
+ sem::BuiltinType two_params[] = {
+ sem::BuiltinType::kAtomicExchange, sem::BuiltinType::kAtomicAdd,
+ sem::BuiltinType::kAtomicSub, sem::BuiltinType::kAtomicMin,
+ sem::BuiltinType::kAtomicMax, sem::BuiltinType::kAtomicAnd,
+ sem::BuiltinType::kAtomicOr, sem::BuiltinType::kAtomicXor,
+ };
+ for (auto& a : two_params) {
+ b.Func(std::string{"stub_"} + sem::str(a) + "_u32",
+ {
+ b.Param("p0", b.ty.u32()),
+ b.Param("p1", b.ty.u32()),
+ },
+ b.ty.u32(), {b.Return(0_u)},
+ {b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), a)});
+ b.Func(std::string{"stub_"} + sem::str(a) + "_i32",
+ {
+ b.Param("p0", b.ty.i32()),
+ b.Param("p1", b.ty.i32()),
+ },
+ b.ty.i32(), {b.Return(0_i)},
+ {b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), a)});
+ }
+
+ b.Func("stub_atomicLoad_u32",
+ {
+ b.Param("p0", b.ty.u32()),
+ },
+ b.ty.u32(), {b.Return(0_u)},
+ {
+ b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), sem::BuiltinType::kAtomicLoad),
+ });
+ b.Func("stub_atomicLoad_i32",
+ {
+ b.Param("p0", b.ty.i32()),
+ },
+ b.ty.i32(), {b.Return(0_i)},
+ {
+ b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), sem::BuiltinType::kAtomicLoad),
+ });
+
+ b.Func("stub_atomicStore_u32",
+ {
+ b.Param("p0", b.ty.u32()),
+ b.Param("p1", b.ty.u32()),
+ },
+ b.ty.void_(), {},
+ {
+ b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), sem::BuiltinType::kAtomicStore),
+ });
+ b.Func("stub_atomicStore_i32",
+ {
+ b.Param("p0", b.ty.i32()),
+ b.Param("p1", b.ty.i32()),
+ },
+ b.ty.void_(), {},
+ {
+ b.ASTNodes().Create<SpirvAtomic::Stub>(b.ID(), sem::BuiltinType::kAtomicStore),
+ });
+
+ b.Func("stub_atomic_compare_exchange_weak_u32",
+ {
+ b.Param("p0", b.ty.u32()),
+ b.Param("p1", b.ty.u32()),
+ b.Param("p2", b.ty.u32()),
+ },
+ b.ty.u32(), {b.Return(0_u)},
+ {
+ b.ASTNodes().Create<SpirvAtomic::Stub>(
+ b.ID(), sem::BuiltinType::kAtomicCompareExchangeWeak),
+ });
+ b.Func("stub_atomic_compare_exchange_weak_i32",
+ {b.Param("p0", b.ty.i32()), b.Param("p1", b.ty.i32()), b.Param("p2", b.ty.i32())},
+ b.ty.i32(), {b.Return(0_i)},
+ {
+ b.ASTNodes().Create<SpirvAtomic::Stub>(
+ b.ID(), sem::BuiltinType::kAtomicCompareExchangeWeak),
+ });
+
+ // Keep this pointer alive after Transform() returns
+ files_.emplace_back(std::move(file));
+
+ return TransformTest::Run<SpirvAtomic>(Program(std::move(b)));
+ }
+
+ private:
+ std::vector<std::unique_ptr<Source::File>> files_;
+};
+
+TEST_F(SpirvAtomicTest, ArrayOfU32) {
+ auto* src = R"(
+var<workgroup> wg : array<u32, 4>;
+
+fn f() {
+ stub_atomicStore_u32(wg[1], 1u);
+}
+)";
+
+ auto* expect = R"(
+var<workgroup> wg : array<atomic<u32>, 4u>;
+
+fn f() {
+ atomicStore(&(wg[1]), 1u);
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ArraysOfU32) {
+ auto* src = R"(
+var<workgroup> wg : array<array<array<u32, 1>, 2>, 3>;
+
+fn f() {
+ stub_atomicStore_u32(wg[2][1][0], 1u);
+}
+)";
+
+ auto* expect = R"(
+var<workgroup> wg : array<array<array<atomic<u32>, 1u>, 2u>, 3u>;
+
+fn f() {
+ atomicStore(&(wg[2][1][0]), 1u);
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AliasedArraysOfU32) {
+ auto* src = R"(
+type A0 = u32;
+
+type A1 = array<A0, 1>;
+
+type A2 = array<A1, 2>;
+
+type A3 = array<A2, 3>;
+
+var<workgroup> wg : A3;
+
+fn f() {
+ stub_atomicStore_u32(wg[2][1][0], 1u);
+}
+)";
+
+ auto* expect = R"(
+type A0 = u32;
+
+type A1 = array<A0, 1>;
+
+type A2 = array<A1, 2>;
+
+type A3 = array<A2, 3>;
+
+var<workgroup> wg : array<array<array<atomic<u32>, 1u>, 2u>, 3u>;
+
+fn f() {
+ atomicStore(&(wg[2][1][0]), 1u);
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, FlatStructSingleAtomic) {
+ auto* src = R"(
+struct S {
+ a : u32,
+}
+
+var<workgroup> wg : S;
+
+fn f() {
+ stub_atomicStore_u32(wg.a, 1u);
+}
+)";
+
+ auto* expect = R"(
+struct S_atomic {
+ a : atomic<u32>,
+}
+
+struct S {
+ a : u32,
+}
+
+var<workgroup> wg : S_atomic;
+
+fn f() {
+ atomicStore(&(wg.a), 1u);
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, FlatStructMultipleAtomic) {
+ auto* src = R"(
+struct S {
+ a : u32,
+ b : i32,
+}
+
+var<workgroup> wg : S;
+
+fn f1() {
+ stub_atomicStore_u32(wg.a, 1u);
+}
+
+fn f2() {
+ stub_atomicStore_i32(wg.b, 2i);
+}
+)";
+
+ auto* expect = R"(
+struct S_atomic {
+ a : atomic<u32>,
+ b : atomic<i32>,
+}
+
+struct S {
+ a : u32,
+ b : i32,
+}
+
+var<workgroup> wg : S_atomic;
+
+fn f1() {
+ atomicStore(&(wg.a), 1u);
+}
+
+fn f2() {
+ atomicStore(&(wg.b), 2i);
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, NestedStruct) {
+ auto* src = R"(
+struct S0 {
+ a : u32,
+ b : i32,
+ c : u32,
+}
+
+struct S1 {
+ a : i32,
+ b : u32,
+ c : S0,
+}
+
+struct S2 {
+ a : i32,
+ b : S1,
+ c : u32,
+}
+
+var<workgroup> wg : S2;
+
+fn f() {
+ stub_atomicStore_u32(wg.b.c.a, 1u);
+}
+)";
+
+ auto* expect = R"(
+struct S0_atomic {
+ a : atomic<u32>,
+ b : i32,
+ c : u32,
+}
+
+struct S0 {
+ a : u32,
+ b : i32,
+ c : u32,
+}
+
+struct S1_atomic {
+ a : i32,
+ b : u32,
+ c : S0_atomic,
+}
+
+struct S1 {
+ a : i32,
+ b : u32,
+ c : S0,
+}
+
+struct S2_atomic {
+ a : i32,
+ b : S1_atomic,
+ c : u32,
+}
+
+struct S2 {
+ a : i32,
+ b : S1,
+ c : u32,
+}
+
+var<workgroup> wg : S2_atomic;
+
+fn f() {
+ atomicStore(&(wg.b.c.a), 1u);
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ArrayOfStruct) {
+ auto* src = R"(
+struct S {
+ a : u32,
+ b : i32,
+ c : u32,
+}
+
+@group(0) @binding(1) var<storage, read_write> arr : array<S>;
+
+fn f() {
+ stub_atomicStore_i32(arr[4].b, 1i);
+}
+)";
+
+ auto* expect = R"(
+struct S_atomic {
+ a : u32,
+ b : atomic<i32>,
+ c : u32,
+}
+
+struct S {
+ a : u32,
+ b : i32,
+ c : u32,
+}
+
+@group(0) @binding(1) var<storage, read_write> arr : array<S_atomic>;
+
+fn f() {
+ atomicStore(&(arr[4].b), 1i);
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, StructOfArray) {
+ auto* src = R"(
+struct S {
+ a : array<i32>,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S;
+
+fn f() {
+ stub_atomicStore_i32(s.a[4], 1i);
+}
+)";
+
+ auto* expect = R"(
+struct S_atomic {
+ a : array<atomic<i32>>,
+}
+
+struct S {
+ a : array<i32>,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S_atomic;
+
+fn f() {
+ atomicStore(&(s.a[4]), 1i);
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ViaPtrLet) {
+ auto* src = R"(
+struct S {
+ i : i32,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S;
+
+fn f() {
+ let p0 = &(s);
+ let p1 : ptr<storage, i32, read_write> = &((*(p0)).i);
+ stub_atomicStore_i32(*p1, 1i);
+}
+)";
+
+ auto* expect =
+ R"(
+struct S_atomic {
+ i : atomic<i32>,
+}
+
+struct S {
+ i : i32,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S_atomic;
+
+fn f() {
+ let p0 = &(s);
+ let p1 : ptr<storage, atomic<i32>, read_write> = &((*(p0)).i);
+ atomicStore(&(*(p1)), 1i);
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, StructIsolatedMixedUsage) {
+ auto* src = R"(
+struct S {
+ i : i32,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S;
+
+fn f() {
+ stub_atomicStore_i32(s.i, 1i);
+}
+
+fn another_usage() {
+ var s : S;
+ let x : i32 = s.i;
+ s.i = 3i;
+}
+)";
+
+ auto* expect =
+ R"(
+struct S_atomic {
+ i : atomic<i32>,
+}
+
+struct S {
+ i : i32,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S_atomic;
+
+fn f() {
+ atomicStore(&(s.i), 1i);
+}
+
+fn another_usage() {
+ var s : S;
+ let x : i32 = s.i;
+ s.i = 3i;
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+// This sort of mixed usage isn't handled yet. Not sure if we need to just yet.
+// If we don't, then the transform should give sensible diagnostics instead of producing invalid
+// WGSL.
+// TODO(crbug.com/tint/1595)
+TEST_F(SpirvAtomicTest, DISABLED_StructComplexMixedUsage) {
+ auto* src = R"(
+struct S {
+ i : i32,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S;
+
+fn f() {
+ let x : i32 = s.i;
+ stub_atomicStore_i32(s.i, 1i);
+ s.i = 3i;
+}
+)";
+
+ auto* expect =
+ R"(
+struct S_atomic {
+ i : atomic<i32>,
+}
+
+struct S {
+ i : i32,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S_atomic;
+
+fn f() {
+ let x : i32 = atomicLoad(&s.i);
+ stub_atomicStore_i32(s.i, 1i);
+ atomicStore(&(s.i), 1i);
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AtomicLoad) {
+ auto* src = R"(
+var<workgroup> wg_u32 : u32;
+var<workgroup> wg_i32 : i32;
+@group(0) @binding(0) var<storage, read_write> sg_u32 : u32;
+@group(0) @binding(1) var<storage, read_write> sg_i32 : i32;
+
+fn f() {
+ {let r = stub_atomicLoad_u32(wg_u32);}
+ {let r = stub_atomicLoad_i32(wg_i32);}
+ {let r = stub_atomicLoad_u32(sg_u32);}
+ {let r = stub_atomicLoad_i32(sg_i32);}
+}
+)";
+
+ auto* expect =
+ R"(
+var<workgroup> wg_u32 : atomic<u32>;
+
+var<workgroup> wg_i32 : atomic<i32>;
+
+@group(0) @binding(0) var<storage, read_write> sg_u32 : atomic<u32>;
+
+@group(0) @binding(1) var<storage, read_write> sg_i32 : atomic<i32>;
+
+fn f() {
+ {
+ let r = atomicLoad(&(wg_u32));
+ }
+ {
+ let r = atomicLoad(&(wg_i32));
+ }
+ {
+ let r = atomicLoad(&(sg_u32));
+ }
+ {
+ let r = atomicLoad(&(sg_i32));
+ }
+}
+)";
+
+ auto got = Run(src);
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AtomicExchange) {
+ auto* src = R"(
+var<workgroup> wg_u32 : u32;
+var<workgroup> wg_i32 : i32;
+@group(0) @binding(0) var<storage, read_write> sg_u32 : u32;
+@group(0) @binding(1) var<storage, read_write> sg_i32 : i32;
+
+fn f() {
+ {let r = stub_atomicExchange_u32(wg_u32, 123u);}
+ {let r = stub_atomicExchange_i32(wg_i32, 123i);}
+ {let r = stub_atomicExchange_u32(sg_u32, 123u);}
+ {let r = stub_atomicExchange_i32(sg_i32, 123i);}
+}
+)";
+
+ auto* expect =
+ R"(
+var<workgroup> wg_u32 : atomic<u32>;
+
+var<workgroup> wg_i32 : atomic<i32>;
+
+@group(0) @binding(0) var<storage, read_write> sg_u32 : atomic<u32>;
+
+@group(0) @binding(1) var<storage, read_write> sg_i32 : atomic<i32>;
+
+fn f() {
+ {
+ let r = atomicExchange(&(wg_u32), 123u);
+ }
+ {
+ let r = atomicExchange(&(wg_i32), 123i);
+ }
+ {
+ let r = atomicExchange(&(sg_u32), 123u);
+ }
+ {
+ let r = atomicExchange(&(sg_i32), 123i);
+ }
+}
+)";
+
+ auto got = Run(src);
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AtomicAdd) {
+ auto* src = R"(
+var<workgroup> wg_u32 : u32;
+var<workgroup> wg_i32 : i32;
+@group(0) @binding(0) var<storage, read_write> sg_u32 : u32;
+@group(0) @binding(1) var<storage, read_write> sg_i32 : i32;
+
+fn f() {
+ {let r = stub_atomicAdd_u32(wg_u32, 123u);}
+ {let r = stub_atomicAdd_i32(wg_i32, 123i);}
+ {let r = stub_atomicAdd_u32(sg_u32, 123u);}
+ {let r = stub_atomicAdd_i32(sg_i32, 123i);}
+}
+)";
+
+ auto* expect =
+ R"(
+var<workgroup> wg_u32 : atomic<u32>;
+
+var<workgroup> wg_i32 : atomic<i32>;
+
+@group(0) @binding(0) var<storage, read_write> sg_u32 : atomic<u32>;
+
+@group(0) @binding(1) var<storage, read_write> sg_i32 : atomic<i32>;
+
+fn f() {
+ {
+ let r = atomicAdd(&(wg_u32), 123u);
+ }
+ {
+ let r = atomicAdd(&(wg_i32), 123i);
+ }
+ {
+ let r = atomicAdd(&(sg_u32), 123u);
+ }
+ {
+ let r = atomicAdd(&(sg_i32), 123i);
+ }
+}
+)";
+
+ auto got = Run(src);
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AtomicSub) {
+ auto* src = R"(
+var<workgroup> wg_u32 : u32;
+var<workgroup> wg_i32 : i32;
+@group(0) @binding(0) var<storage, read_write> sg_u32 : u32;
+@group(0) @binding(1) var<storage, read_write> sg_i32 : i32;
+
+fn f() {
+ {let r = stub_atomicSub_u32(wg_u32, 123u);}
+ {let r = stub_atomicSub_i32(wg_i32, 123i);}
+ {let r = stub_atomicSub_u32(sg_u32, 123u);}
+ {let r = stub_atomicSub_i32(sg_i32, 123i);}
+}
+)";
+
+ auto* expect =
+ R"(
+var<workgroup> wg_u32 : atomic<u32>;
+
+var<workgroup> wg_i32 : atomic<i32>;
+
+@group(0) @binding(0) var<storage, read_write> sg_u32 : atomic<u32>;
+
+@group(0) @binding(1) var<storage, read_write> sg_i32 : atomic<i32>;
+
+fn f() {
+ {
+ let r = atomicSub(&(wg_u32), 123u);
+ }
+ {
+ let r = atomicSub(&(wg_i32), 123i);
+ }
+ {
+ let r = atomicSub(&(sg_u32), 123u);
+ }
+ {
+ let r = atomicSub(&(sg_i32), 123i);
+ }
+}
+)";
+
+ auto got = Run(src);
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AtomicMin) {
+ auto* src = R"(
+var<workgroup> wg_u32 : u32;
+var<workgroup> wg_i32 : i32;
+@group(0) @binding(0) var<storage, read_write> sg_u32 : u32;
+@group(0) @binding(1) var<storage, read_write> sg_i32 : i32;
+
+fn f() {
+ {let r = stub_atomicMin_u32(wg_u32, 123u);}
+ {let r = stub_atomicMin_i32(wg_i32, 123i);}
+ {let r = stub_atomicMin_u32(sg_u32, 123u);}
+ {let r = stub_atomicMin_i32(sg_i32, 123i);}
+}
+)";
+
+ auto* expect =
+ R"(
+var<workgroup> wg_u32 : atomic<u32>;
+
+var<workgroup> wg_i32 : atomic<i32>;
+
+@group(0) @binding(0) var<storage, read_write> sg_u32 : atomic<u32>;
+
+@group(0) @binding(1) var<storage, read_write> sg_i32 : atomic<i32>;
+
+fn f() {
+ {
+ let r = atomicMin(&(wg_u32), 123u);
+ }
+ {
+ let r = atomicMin(&(wg_i32), 123i);
+ }
+ {
+ let r = atomicMin(&(sg_u32), 123u);
+ }
+ {
+ let r = atomicMin(&(sg_i32), 123i);
+ }
+}
+)";
+
+ auto got = Run(src);
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AtomicMax) {
+ auto* src = R"(
+var<workgroup> wg_u32 : u32;
+var<workgroup> wg_i32 : i32;
+@group(0) @binding(0) var<storage, read_write> sg_u32 : u32;
+@group(0) @binding(1) var<storage, read_write> sg_i32 : i32;
+
+fn f() {
+ {let r = stub_atomicMax_u32(wg_u32, 123u);}
+ {let r = stub_atomicMax_i32(wg_i32, 123i);}
+ {let r = stub_atomicMax_u32(sg_u32, 123u);}
+ {let r = stub_atomicMax_i32(sg_i32, 123i);}
+}
+)";
+
+ auto* expect =
+ R"(
+var<workgroup> wg_u32 : atomic<u32>;
+
+var<workgroup> wg_i32 : atomic<i32>;
+
+@group(0) @binding(0) var<storage, read_write> sg_u32 : atomic<u32>;
+
+@group(0) @binding(1) var<storage, read_write> sg_i32 : atomic<i32>;
+
+fn f() {
+ {
+ let r = atomicMax(&(wg_u32), 123u);
+ }
+ {
+ let r = atomicMax(&(wg_i32), 123i);
+ }
+ {
+ let r = atomicMax(&(sg_u32), 123u);
+ }
+ {
+ let r = atomicMax(&(sg_i32), 123i);
+ }
+}
+)";
+
+ auto got = Run(src);
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AtomicAnd) {
+ auto* src = R"(
+var<workgroup> wg_u32 : u32;
+var<workgroup> wg_i32 : i32;
+@group(0) @binding(0) var<storage, read_write> sg_u32 : u32;
+@group(0) @binding(1) var<storage, read_write> sg_i32 : i32;
+
+fn f() {
+ {let r = stub_atomicAnd_u32(wg_u32, 123u);}
+ {let r = stub_atomicAnd_i32(wg_i32, 123i);}
+ {let r = stub_atomicAnd_u32(sg_u32, 123u);}
+ {let r = stub_atomicAnd_i32(sg_i32, 123i);}
+}
+)";
+
+ auto* expect =
+ R"(
+var<workgroup> wg_u32 : atomic<u32>;
+
+var<workgroup> wg_i32 : atomic<i32>;
+
+@group(0) @binding(0) var<storage, read_write> sg_u32 : atomic<u32>;
+
+@group(0) @binding(1) var<storage, read_write> sg_i32 : atomic<i32>;
+
+fn f() {
+ {
+ let r = atomicAnd(&(wg_u32), 123u);
+ }
+ {
+ let r = atomicAnd(&(wg_i32), 123i);
+ }
+ {
+ let r = atomicAnd(&(sg_u32), 123u);
+ }
+ {
+ let r = atomicAnd(&(sg_i32), 123i);
+ }
+}
+)";
+
+ auto got = Run(src);
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AtomicOr) {
+ auto* src = R"(
+var<workgroup> wg_u32 : u32;
+var<workgroup> wg_i32 : i32;
+@group(0) @binding(0) var<storage, read_write> sg_u32 : u32;
+@group(0) @binding(1) var<storage, read_write> sg_i32 : i32;
+
+fn f() {
+ {let r = stub_atomicOr_u32(wg_u32, 123u);}
+ {let r = stub_atomicOr_i32(wg_i32, 123i);}
+ {let r = stub_atomicOr_u32(sg_u32, 123u);}
+ {let r = stub_atomicOr_i32(sg_i32, 123i);}
+}
+)";
+
+ auto* expect =
+ R"(
+var<workgroup> wg_u32 : atomic<u32>;
+
+var<workgroup> wg_i32 : atomic<i32>;
+
+@group(0) @binding(0) var<storage, read_write> sg_u32 : atomic<u32>;
+
+@group(0) @binding(1) var<storage, read_write> sg_i32 : atomic<i32>;
+
+fn f() {
+ {
+ let r = atomicOr(&(wg_u32), 123u);
+ }
+ {
+ let r = atomicOr(&(wg_i32), 123i);
+ }
+ {
+ let r = atomicOr(&(sg_u32), 123u);
+ }
+ {
+ let r = atomicOr(&(sg_i32), 123i);
+ }
+}
+)";
+
+ auto got = Run(src);
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AtomicXor) {
+ auto* src = R"(
+var<workgroup> wg_u32 : u32;
+var<workgroup> wg_i32 : i32;
+@group(0) @binding(0) var<storage, read_write> sg_u32 : u32;
+@group(0) @binding(1) var<storage, read_write> sg_i32 : i32;
+
+fn f() {
+ {let r = stub_atomicXor_u32(wg_u32, 123u);}
+ {let r = stub_atomicXor_i32(wg_i32, 123i);}
+ {let r = stub_atomicXor_u32(sg_u32, 123u);}
+ {let r = stub_atomicXor_i32(sg_i32, 123i);}
+}
+)";
+
+ auto* expect =
+ R"(
+var<workgroup> wg_u32 : atomic<u32>;
+
+var<workgroup> wg_i32 : atomic<i32>;
+
+@group(0) @binding(0) var<storage, read_write> sg_u32 : atomic<u32>;
+
+@group(0) @binding(1) var<storage, read_write> sg_i32 : atomic<i32>;
+
+fn f() {
+ {
+ let r = atomicXor(&(wg_u32), 123u);
+ }
+ {
+ let r = atomicXor(&(wg_i32), 123i);
+ }
+ {
+ let r = atomicXor(&(sg_u32), 123u);
+ }
+ {
+ let r = atomicXor(&(sg_i32), 123i);
+ }
+}
+)";
+
+ auto got = Run(src);
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, AtomicCompareExchangeWeak) {
+ auto* src = R"(
+var<workgroup> wg_u32 : u32;
+var<workgroup> wg_i32 : i32;
+@group(0) @binding(0) var<storage, read_write> sg_u32 : u32;
+@group(0) @binding(1) var<storage, read_write> sg_i32 : i32;
+
+fn f() {
+ {let r = stub_atomic_compare_exchange_weak_u32(wg_u32, 123u, 456u);}
+ {let r = stub_atomic_compare_exchange_weak_i32(wg_i32, 123i, 456i);}
+ {let r = stub_atomic_compare_exchange_weak_u32(sg_u32, 123u, 456u);}
+ {let r = stub_atomic_compare_exchange_weak_i32(sg_i32, 123i, 456i);}
+}
+)";
+
+ auto* expect =
+ R"(
+var<workgroup> wg_u32 : atomic<u32>;
+
+var<workgroup> wg_i32 : atomic<i32>;
+
+@group(0) @binding(0) var<storage, read_write> sg_u32 : atomic<u32>;
+
+@group(0) @binding(1) var<storage, read_write> sg_i32 : atomic<i32>;
+
+fn f() {
+ {
+ let old_value = atomicCompareExchangeWeak(&(wg_u32), 123u, 456u).old_value;
+ let r = old_value;
+ }
+ {
+ let old_value_2 = atomicCompareExchangeWeak(&(wg_i32), 123i, 456i).old_value;
+ let r = old_value_2;
+ }
+ {
+ let old_value_1 = atomicCompareExchangeWeak(&(sg_u32), 123u, 456u).old_value;
+ let r = old_value_1;
+ }
+ {
+ let old_value_3 = atomicCompareExchangeWeak(&(sg_i32), 123i, 456i).old_value;
+ let r = old_value_3;
+ }
+}
+)";
+
+ auto got = Run(src);
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ReplaceAssignsAndDecls_Scaler) {
+ auto* src = R"(
+var<workgroup> wg : u32;
+
+fn f() {
+ stub_atomicAdd_u32(wg, 1u);
+
+ wg = 0u;
+ let a = wg;
+ var b : u32;
+ b = wg;
+}
+)";
+
+ auto* expect = R"(
+var<workgroup> wg : atomic<u32>;
+
+fn f() {
+ atomicAdd(&(wg), 1u);
+ atomicStore(&(wg), 0u);
+ let a = atomicLoad(&(wg));
+ var b : u32;
+ b = atomicLoad(&(wg));
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ReplaceAssignsAndDecls_Struct) {
+ auto* src = R"(
+struct S {
+ a : u32,
+}
+
+var<workgroup> wg : S;
+
+fn f() {
+ stub_atomicAdd_u32(wg.a, 1u);
+
+ wg.a = 0u;
+ let a = wg.a;
+ var b : u32;
+ b = wg.a;
+}
+)";
+
+ auto* expect = R"(
+struct S_atomic {
+ a : atomic<u32>,
+}
+
+struct S {
+ a : u32,
+}
+
+var<workgroup> wg : S_atomic;
+
+fn f() {
+ atomicAdd(&(wg.a), 1u);
+ atomicStore(&(wg.a), 0u);
+ let a = atomicLoad(&(wg.a));
+ var b : u32;
+ b = atomicLoad(&(wg.a));
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ReplaceAssignsAndDecls_NestedStruct) {
+ auto* src = R"(
+struct S0 {
+ a : u32,
+}
+
+struct S1 {
+ s0 : S0
+}
+
+var<workgroup> wg : S1;
+
+fn f() {
+ stub_atomicAdd_u32(wg.s0.a, 1u);
+
+ wg.s0.a = 0u;
+ let a = wg.s0.a;
+ var b : u32;
+ b = wg.s0.a;
+}
+)";
+
+ auto* expect = R"(
+struct S0_atomic {
+ a : atomic<u32>,
+}
+
+struct S0 {
+ a : u32,
+}
+
+struct S1_atomic {
+ s0 : S0_atomic,
+}
+
+struct S1 {
+ s0 : S0,
+}
+
+var<workgroup> wg : S1_atomic;
+
+fn f() {
+ atomicAdd(&(wg.s0.a), 1u);
+ atomicStore(&(wg.s0.a), 0u);
+ let a = atomicLoad(&(wg.s0.a));
+ var b : u32;
+ b = atomicLoad(&(wg.s0.a));
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ReplaceAssignsAndDecls_StructMultipleAtomics) {
+ auto* src = R"(
+struct S {
+ a : u32,
+ b : u32,
+ c : u32,
+}
+
+var<workgroup> wg : S;
+
+fn f() {
+ stub_atomicAdd_u32(wg.a, 1u);
+ stub_atomicAdd_u32(wg.b, 1u);
+
+ wg.a = 0u;
+ let a = wg.a;
+ var b : u32;
+ b = wg.a;
+
+ wg.b = 0u;
+ let c = wg.b;
+ var d : u32;
+ d = wg.b;
+
+ wg.c = 0u;
+ let e = wg.c;
+ var f : u32;
+ f = wg.c;
+}
+)";
+
+ auto* expect = R"(
+struct S_atomic {
+ a : atomic<u32>,
+ b : atomic<u32>,
+ c : u32,
+}
+
+struct S {
+ a : u32,
+ b : u32,
+ c : u32,
+}
+
+var<workgroup> wg : S_atomic;
+
+fn f() {
+ atomicAdd(&(wg.a), 1u);
+ atomicAdd(&(wg.b), 1u);
+ atomicStore(&(wg.a), 0u);
+ let a = atomicLoad(&(wg.a));
+ var b : u32;
+ b = atomicLoad(&(wg.a));
+ atomicStore(&(wg.b), 0u);
+ let c = atomicLoad(&(wg.b));
+ var d : u32;
+ d = atomicLoad(&(wg.b));
+ wg.c = 0u;
+ let e = wg.c;
+ var f : u32;
+ f = wg.c;
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ReplaceAssignsAndDecls_ArrayOfScalar) {
+ auto* src = R"(
+var<workgroup> wg : array<u32, 4>;
+
+fn f() {
+ stub_atomicAdd_u32(wg[1], 1u);
+
+ wg[1] = 0u;
+ let a = wg[1];
+ var b : u32;
+ b = wg[1];
+}
+)";
+
+ auto* expect = R"(
+var<workgroup> wg : array<atomic<u32>, 4u>;
+
+fn f() {
+ atomicAdd(&(wg[1]), 1u);
+ atomicStore(&(wg[1]), 0u);
+ let a = atomicLoad(&(wg[1]));
+ var b : u32;
+ b = atomicLoad(&(wg[1]));
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ReplaceAssignsAndDecls_ArrayOfStruct) {
+ auto* src = R"(
+struct S {
+ a : u32,
+}
+
+var<workgroup> wg : array<S, 4>;
+
+fn f() {
+ stub_atomicAdd_u32(wg[1].a, 1u);
+
+ wg[1].a = 0u;
+ let a = wg[1].a;
+ var b : u32;
+ b = wg[1].a;
+}
+)";
+
+ auto* expect = R"(
+struct S_atomic {
+ a : atomic<u32>,
+}
+
+struct S {
+ a : u32,
+}
+
+var<workgroup> wg : array<S_atomic, 4u>;
+
+fn f() {
+ atomicAdd(&(wg[1].a), 1u);
+ atomicStore(&(wg[1].a), 0u);
+ let a = atomicLoad(&(wg[1].a));
+ var b : u32;
+ b = atomicLoad(&(wg[1].a));
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ReplaceAssignsAndDecls_StructOfArray) {
+ auto* src = R"(
+struct S {
+ a : array<u32>,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S;
+
+fn f() {
+ stub_atomicAdd_u32(s.a[4], 1u);
+
+ s.a[4] = 0u;
+ let a = s.a[4];
+ var b : u32;
+ b = s.a[4];
+}
+)";
+
+ auto* expect = R"(
+struct S_atomic {
+ a : array<atomic<u32>>,
+}
+
+struct S {
+ a : array<u32>,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S_atomic;
+
+fn f() {
+ atomicAdd(&(s.a[4]), 1u);
+ atomicStore(&(s.a[4]), 0u);
+ let a = atomicLoad(&(s.a[4]));
+ var b : u32;
+ b = atomicLoad(&(s.a[4]));
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(SpirvAtomicTest, ReplaceAssignsAndDecls_ViaPtrLet) {
+ auto* src = R"(
+struct S {
+ i : u32,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S;
+
+fn f() {
+ let p0 = &(s);
+ let p1 : ptr<storage, u32, read_write> = &((*(p0)).i);
+ stub_atomicAdd_u32(*p1, 1u);
+
+ *p1 = 0u;
+ let a = *p1;
+ var b : u32;
+ b = *p1;
+}
+)";
+
+ auto* expect = R"(
+struct S_atomic {
+ i : atomic<u32>,
+}
+
+struct S {
+ i : u32,
+}
+
+@group(0) @binding(1) var<storage, read_write> s : S_atomic;
+
+fn f() {
+ let p0 = &(s);
+ let p1 : ptr<storage, atomic<u32>, read_write> = &((*(p0)).i);
+ atomicAdd(&(*(p1)), 1u);
+ atomicStore(&(*(p1)), 0u);
+ let a = atomicLoad(&(*(p1)));
+ var b : u32;
+ b = atomicLoad(&(*(p1)));
+}
+)";
+
+ auto got = Run(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+} // namespace
+} // namespace tint::transform
diff --git a/src/tint/transform/unshadow.cc b/src/tint/transform/unshadow.cc
index 6f0292b..952a88b 100644
--- a/src/tint/transform/unshadow.cc
+++ b/src/tint/transform/unshadow.cc
@@ -63,6 +63,9 @@
[&](const ast::Let*) {
return ctx.dst->Let(source, symbol, type, constructor, attributes);
},
+ [&](const ast::Const*) {
+ return ctx.dst->Const(source, symbol, type, constructor, attributes);
+ },
[&](const ast::Parameter*) {
return ctx.dst->Param(source, symbol, type, attributes);
},
diff --git a/src/tint/transform/unshadow_test.cc b/src/tint/transform/unshadow_test.cc
index 30e1db5..f5a8102 100644
--- a/src/tint/transform/unshadow_test.cc
+++ b/src/tint/transform/unshadow_test.cc
@@ -34,14 +34,16 @@
auto* src = R"(
var<private> a : i32;
-let b : i32 = 1;
+const b : i32 = 1;
fn F(c : i32) {
var d : i32;
let e : i32 = 1;
+ const f : i32 = 2;
{
- var f : i32;
- let g : i32 = 1;
+ var g : i32;
+ let h : i32 = 1;
+ const i : i32 = 2;
}
}
)";
@@ -64,6 +66,10 @@
fn Y() {
let a = true;
}
+
+fn Z() {
+ const a = true;
+}
)";
auto* expect = R"(
@@ -76,6 +82,10 @@
fn Y() {
let a_2 = true;
}
+
+fn Z() {
+ const a_3 = true;
+}
)";
auto got = Run<Unshadow>(src);
@@ -93,6 +103,10 @@
let a = true;
}
+fn Z() {
+ const a = true;
+}
+
type a = i32;
)";
@@ -105,6 +119,10 @@
let a_2 = true;
}
+fn Z() {
+ const a_3 = true;
+}
+
type a = i32;
)";
@@ -126,6 +144,10 @@
fn Y() {
let a = false;
}
+
+fn Z() {
+ const a = false;
+}
)";
auto* expect = R"(
@@ -140,6 +162,10 @@
fn Y() {
let a_2 = false;
}
+
+fn Z() {
+ const a_3 = false;
+}
)";
auto got = Run<Unshadow>(src);
@@ -157,6 +183,10 @@
let a = false;
}
+fn Z() {
+ const a = false;
+}
+
struct a {
m : i32,
};
@@ -172,6 +202,10 @@
let a_2 = false;
}
+fn Z() {
+ const a_3 = false;
+}
+
struct a {
m : i32,
}
@@ -187,11 +221,19 @@
fn a() {
var a = true;
var b = false;
+ var c = true;
}
fn b() {
let a = true;
let b = false;
+ let c = true;
+}
+
+fn c() {
+ const a = true;
+ const b = false;
+ const c = true;
}
)";
@@ -199,11 +241,19 @@
fn a() {
var a_1 = true;
var b_1 = false;
+ var c_1 = true;
}
fn b() {
let a_2 = true;
let b_2 = false;
+ let c_2 = true;
+}
+
+fn c() {
+ const a_3 = true;
+ const b_3 = false;
+ const c_3 = true;
}
)";
@@ -217,24 +267,39 @@
fn b() {
let a = true;
let b = false;
+ let c = true;
}
fn a() {
var a = true;
var b = false;
+ var c = true;
}
+fn c() {
+ const a = true;
+ const b = false;
+ const c = true;
+}
)";
auto* expect = R"(
fn b() {
let a_1 = true;
let b_1 = false;
+ let c_1 = true;
}
fn a() {
var a_2 = true;
var b_2 = false;
+ var c_2 = true;
+}
+
+fn c() {
+ const a_3 = true;
+ const b_3 = false;
+ const c_3 = true;
}
)";
@@ -254,6 +319,10 @@
fn Y() {
let a = (a == 321);
}
+
+fn Z() {
+ const a = 321;
+}
)";
auto* expect = R"(
@@ -266,6 +335,10 @@
fn Y() {
let a_2 = (a == 321);
}
+
+fn Z() {
+ const a_3 = 321;
+}
)";
auto got = Run<Unshadow>(src);
@@ -283,6 +356,10 @@
let a = (a == 321);
}
+fn Z() {
+ const a = 321;
+}
+
var<private> a : i32;
)";
@@ -295,6 +372,10 @@
let a_2 = (a == 321);
}
+fn Z() {
+ const a_3 = 321;
+}
+
var<private> a : i32;
)";
@@ -314,10 +395,14 @@
fn Y() {
let a = (a == 321);
}
+
+fn Z() {
+ const a = 321;
+}
)";
auto* expect = R"(
-let a : i32 = 1;
+const a : i32 = 1;
fn X() {
var a_1 = (a == 123);
@@ -326,6 +411,10 @@
fn Y() {
let a_2 = (a == 321);
}
+
+fn Z() {
+ const a_3 = 321;
+}
)";
auto got = Run<Unshadow>(src);
@@ -343,6 +432,10 @@
let a = (a == 321);
}
+fn Z() {
+ const a = 321;
+}
+
let a : i32 = 1;
)";
@@ -355,7 +448,87 @@
let a_2 = (a == 321);
}
-let a : i32 = 1;
+fn Z() {
+ const a_3 = 321;
+}
+
+const a : i32 = 1;
+)";
+
+ auto got = Run<Unshadow>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(UnshadowTest, LocalShadowsGlobalConst) {
+ auto* src = R"(
+const a : i32 = 1;
+
+fn X() {
+ var a = (a == 123);
+}
+
+fn Y() {
+ let a = (a == 321);
+}
+
+fn Z() {
+ const a = 321;
+}
+)";
+
+ auto* expect = R"(
+const a : i32 = 1;
+
+fn X() {
+ var a_1 = (a == 123);
+}
+
+fn Y() {
+ let a_2 = (a == 321);
+}
+
+fn Z() {
+ const a_3 = 321;
+}
+)";
+
+ auto got = Run<Unshadow>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(UnshadowTest, LocalShadowsGlobalConst_OutOfOrder) {
+ auto* src = R"(
+fn X() {
+ var a = (a == 123);
+}
+
+fn Y() {
+ let a = (a == 321);
+}
+
+fn Z() {
+ const a = a;
+}
+
+const a : i32 = 1;
+)";
+
+ auto* expect = R"(
+fn X() {
+ var a_1 = (a == 123);
+}
+
+fn Y() {
+ let a_2 = (a == 321);
+}
+
+fn Z() {
+ const a_3 = a;
+}
+
+const a : i32 = 1;
)";
auto got = Run<Unshadow>(src);
@@ -373,6 +546,9 @@
{
let a = (a == 321);
}
+ {
+ const a = 321;
+ }
}
)";
@@ -385,6 +561,9 @@
{
let a_2 = (a == 321);
}
+ {
+ const a_3 = 321;
+ }
}
)";
@@ -403,6 +582,9 @@
{
let a = (a == 321);
}
+ {
+ const a = 321;
+ }
}
)";
@@ -415,6 +597,45 @@
{
let a_2 = (a == 321);
}
+ {
+ const a_3 = 321;
+ }
+}
+)";
+
+ auto got = Run<Unshadow>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(UnshadowTest, LocalShadowsLocalConst) {
+ auto* src = R"(
+fn X() {
+ const a = 1;
+ {
+ var a = (a == 123);
+ }
+ {
+ let a = (a == 321);
+ }
+ {
+ const a = a;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn X() {
+ const a = 1;
+ {
+ var a_1 = (a == 123);
+ }
+ {
+ let a_2 = (a == 321);
+ }
+ {
+ const a_3 = a;
+ }
}
)";
@@ -432,6 +653,9 @@
{
let a = (a == 321);
}
+ {
+ const a = 321;
+ }
}
)";
@@ -443,6 +667,9 @@
{
let a_2 = (a == 321);
}
+ {
+ const a_3 = 321;
+ }
}
)";
@@ -460,6 +687,9 @@
{
let a = (a == 321);
}
+ {
+ const a = 321;
+ }
}
)";
@@ -471,6 +701,9 @@
{
let a_3 = (a_1 == 321);
}
+ {
+ const a_4 = 321;
+ }
}
)";
@@ -508,7 +741,7 @@
)";
auto* expect = R"(
-let a : i32 = 1;
+const a : i32 = 1;
fn F(a_1 : bool) {
}
@@ -531,7 +764,47 @@
fn F(a_1 : bool) {
}
-let a : i32 = 1;
+const a : i32 = 1;
+)";
+
+ auto got = Run<Unshadow>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(UnshadowTest, ParamShadowsGlobalConst) {
+ auto* src = R"(
+const a : i32 = 1;
+
+fn F(a : bool) {
+}
+)";
+
+ auto* expect = R"(
+const a : i32 = 1;
+
+fn F(a_1 : bool) {
+}
+)";
+
+ auto got = Run<Unshadow>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(UnshadowTest, ParamShadowsGlobalConst_OutOfOrder) {
+ auto* src = R"(
+fn F(a : bool) {
+}
+
+const a : i32 = 1;
+)";
+
+ auto* expect = R"(
+fn F(a_1 : bool) {
+}
+
+const a : i32 = 1;
)";
auto got = Run<Unshadow>(src);
diff --git a/src/tint/transform/unwind_discard_functions.cc b/src/tint/transform/unwind_discard_functions.cc
index a7877e1..d41ef6c 100644
--- a/src/tint/transform/unwind_discard_functions.cc
+++ b/src/tint/transform/unwind_discard_functions.cc
@@ -54,8 +54,8 @@
Symbol ModuleDiscardVarName() {
if (!module_discard_var_name.IsValid()) {
module_discard_var_name = b.Symbols().New("tint_discard");
- ctx.dst->Global(module_discard_var_name, b.ty.bool_(), b.Expr(false),
- ast::StorageClass::kPrivate);
+ ctx.dst->GlobalVar(module_discard_var_name, b.ty.bool_(), b.Expr(false),
+ ast::StorageClass::kPrivate);
}
return module_discard_var_name;
}
diff --git a/src/tint/transform/utils/hoist_to_decl_before.cc b/src/tint/transform/utils/hoist_to_decl_before.cc
index 41f2287..2995522 100644
--- a/src/tint/transform/utils/hoist_to_decl_before.cc
+++ b/src/tint/transform/utils/hoist_to_decl_before.cc
@@ -16,7 +16,7 @@
#include <unordered_map>
-#include "src/tint/ast/variable_decl_statement.h"
+#include "src/tint/program_builder.h"
#include "src/tint/sem/block_statement.h"
#include "src/tint/sem/for_loop_statement.h"
#include "src/tint/sem/if_statement.h"
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 46d5551..22784ba 100644
--- a/src/tint/transform/utils/hoist_to_decl_before_test.cc
+++ b/src/tint/transform/utils/hoist_to_decl_before_test.cc
@@ -17,6 +17,7 @@
#include "gtest/gtest-spi.h"
#include "src/tint/program_builder.h"
#include "src/tint/sem/if_statement.h"
+#include "src/tint/sem/index_accessor_expression.h"
#include "src/tint/sem/statement.h"
#include "src/tint/transform/test_helper.h"
#include "src/tint/transform/utils/hoist_to_decl_before.h"
diff --git a/src/tint/transform/var_for_dynamic_index_test.cc b/src/tint/transform/var_for_dynamic_index_test.cc
index ca767c9..05c19b3 100644
--- a/src/tint/transform/var_for_dynamic_index_test.cc
+++ b/src/tint/transform/var_for_dynamic_index_test.cc
@@ -484,7 +484,8 @@
fn f() {
let p = array<i32, 4>(1, 2, 3, 4);
let c = 1;
- let x = p[c];
+ var var_for_index = p;
+ let x = var_for_index[c];
}
)";
@@ -501,7 +502,8 @@
fn f() {
let p = mat2x2(1.0, 2.0, 3.0, 4.0);
let c = 1;
- let x = p[c];
+ var var_for_index = p;
+ let x = var_for_index[c];
}
)";
diff --git a/src/tint/transform/vertex_pulling.cc b/src/tint/transform/vertex_pulling.cc
index a1627e2..50b8f28 100644
--- a/src/tint/transform/vertex_pulling.cc
+++ b/src/tint/transform/vertex_pulling.cc
@@ -259,12 +259,12 @@
});
for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
// The decorated variable with struct type
- ctx.dst->Global(GetVertexBufferName(i), ctx.dst->ty.Of(struct_type),
- ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- ctx.dst->create<ast::BindingAttribute>(i),
- ctx.dst->create<ast::GroupAttribute>(cfg.pulling_group),
- });
+ ctx.dst->GlobalVar(GetVertexBufferName(i), ctx.dst->ty.Of(struct_type),
+ ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ ctx.dst->create<ast::BindingAttribute>(i),
+ ctx.dst->create<ast::GroupAttribute>(cfg.pulling_group),
+ });
}
}
diff --git a/src/tint/transform/wrap_arrays_in_structs.cc b/src/tint/transform/wrap_arrays_in_structs.cc
deleted file mode 100644
index eb133d7..0000000
--- a/src/tint/transform/wrap_arrays_in_structs.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2021 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/transform/wrap_arrays_in_structs.h"
-
-#include <utility>
-
-#include "src/tint/program_builder.h"
-#include "src/tint/sem/array.h"
-#include "src/tint/sem/call.h"
-#include "src/tint/sem/expression.h"
-#include "src/tint/sem/type_constructor.h"
-#include "src/tint/utils/map.h"
-#include "src/tint/utils/transform.h"
-
-TINT_INSTANTIATE_TYPEINFO(tint::transform::WrapArraysInStructs);
-
-namespace tint::transform {
-
-WrapArraysInStructs::WrappedArrayInfo::WrappedArrayInfo() = default;
-WrapArraysInStructs::WrappedArrayInfo::WrappedArrayInfo(const WrappedArrayInfo&) = default;
-WrapArraysInStructs::WrappedArrayInfo::~WrappedArrayInfo() = default;
-
-WrapArraysInStructs::WrapArraysInStructs() = default;
-
-WrapArraysInStructs::~WrapArraysInStructs() = default;
-
-bool WrapArraysInStructs::ShouldRun(const Program* program, const DataMap&) const {
- for (auto* node : program->ASTNodes().Objects()) {
- if (program->Sem().Get<sem::Array>(node->As<ast::Type>())) {
- return true;
- }
- }
- return false;
-}
-
-void WrapArraysInStructs::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
- auto& sem = ctx.src->Sem();
-
- std::unordered_map<const sem::Array*, WrappedArrayInfo> wrapped_arrays;
- auto wrapper = [&](const sem::Array* array) { return WrapArray(ctx, wrapped_arrays, array); };
- auto wrapper_typename = [&](const sem::Array* arr) -> ast::TypeName* {
- auto info = wrapper(arr);
- return info ? ctx.dst->create<ast::TypeName>(info.wrapper_name) : nullptr;
- };
-
- // Replace all array types with their corresponding wrapper
- ctx.ReplaceAll([&](const ast::Type* ast_type) -> const ast::Type* {
- auto* type = ctx.src->TypeOf(ast_type);
- if (auto* array = type->UnwrapRef()->As<sem::Array>()) {
- return wrapper_typename(array);
- }
- return nullptr;
- });
-
- // Fix up index accessors so `a[1]` becomes `a.arr[1]`
- ctx.ReplaceAll(
- [&](const ast::IndexAccessorExpression* accessor) -> const ast::IndexAccessorExpression* {
- if (auto* array =
- ::tint::As<sem::Array>(sem.Get(accessor->object)->Type()->UnwrapRef())) {
- if (wrapper(array)) {
- // Array is wrapped in a structure. Emit a member accessor to get
- // to the actual array.
- auto* arr = ctx.Clone(accessor->object);
- auto* idx = ctx.Clone(accessor->index);
- auto* unwrapped = ctx.dst->MemberAccessor(arr, "arr");
- return ctx.dst->IndexAccessor(accessor->source, unwrapped, idx);
- }
- }
- return nullptr;
- });
-
- // Fix up array constructors so `A(1,2)` becomes `tint_array_wrapper(A(1,2))`
- ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::Expression* {
- if (auto* call = sem.Get(expr)->UnwrapMaterialize()->As<sem::Call>()) {
- if (auto* ctor = call->Target()->As<sem::TypeConstructor>()) {
- if (auto* array = ctor->ReturnType()->As<sem::Array>()) {
- if (auto w = wrapper(array)) {
- // Wrap the array type constructor with another constructor for
- // the wrapper
- auto* wrapped_array_ty = ctx.dst->ty.type_name(w.wrapper_name);
- auto* array_ty = w.array_type(ctx);
- auto args = utils::Transform(call->Arguments(),
- [&](const tint::sem::Expression* s) {
- return ctx.Clone(s->Declaration());
- });
- auto* arr_ctor = ctx.dst->Construct(array_ty, args);
- return ctx.dst->Construct(wrapped_array_ty, arr_ctor);
- }
- }
- }
- }
- return nullptr;
- });
-
- ctx.Clone();
-}
-
-WrapArraysInStructs::WrappedArrayInfo WrapArraysInStructs::WrapArray(
- CloneContext& ctx,
- std::unordered_map<const sem::Array*, WrappedArrayInfo>& wrapped_arrays,
- const sem::Array* array) const {
- if (array->IsRuntimeSized()) {
- return {}; // We don't want to wrap runtime sized arrays
- }
-
- return utils::GetOrCreate(wrapped_arrays, array, [&] {
- WrappedArrayInfo info;
-
- // Generate a unique name for the array wrapper
- info.wrapper_name = ctx.dst->Symbols().New("tint_array_wrapper");
-
- // Examine the element type. Is it also an array?
- std::function<const ast::Type*(CloneContext&)> el_type;
- if (auto* el_array = array->ElemType()->As<sem::Array>()) {
- // Array of array - call WrapArray() on the element type
- if (auto el = WrapArray(ctx, wrapped_arrays, el_array)) {
- el_type = [=](CloneContext& c) {
- return c.dst->create<ast::TypeName>(el.wrapper_name);
- };
- }
- }
-
- // If the element wasn't an array, just create the typical AST type for it
- if (!el_type) {
- el_type = [=](CloneContext& c) { return CreateASTTypeFor(c, array->ElemType()); };
- }
-
- // Construct the single structure field type
- info.array_type = [=](CloneContext& c) {
- ast::AttributeList attrs;
- if (!array->IsStrideImplicit()) {
- attrs.emplace_back(c.dst->create<ast::StrideAttribute>(array->Stride()));
- }
- return c.dst->ty.array(el_type(c), u32(array->Count()), std::move(attrs));
- };
-
- // Structure() will create and append the ast::Struct to the
- // global declarations of `ctx.dst`. As we haven't finished building the
- // current module-scope statement or function, this will be placed
- // immediately before the usage.
- ctx.dst->Structure(info.wrapper_name, {ctx.dst->Member("arr", info.array_type(ctx))});
- return info;
- });
-}
-
-} // namespace tint::transform
diff --git a/src/tint/transform/wrap_arrays_in_structs.h b/src/tint/transform/wrap_arrays_in_structs.h
deleted file mode 100644
index 4653c6b..0000000
--- a/src/tint/transform/wrap_arrays_in_structs.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2021 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_TRANSFORM_WRAP_ARRAYS_IN_STRUCTS_H_
-#define SRC_TINT_TRANSFORM_WRAP_ARRAYS_IN_STRUCTS_H_
-
-#include <string>
-#include <unordered_map>
-
-#include "src/tint/transform/transform.h"
-
-// Forward declarations
-namespace tint::ast {
-class Type;
-} // namespace tint::ast
-
-namespace tint::transform {
-
-/// WrapArraysInStructs is a transform that replaces all array types with a
-/// structure holding a single field of that array type.
-/// Array index expressions and constructors are also adjusted to deal with this
-/// wrapping.
-/// This transform helps with backends that cannot directly return arrays or use
-/// them as parameters.
-class WrapArraysInStructs : public Castable<WrapArraysInStructs, Transform> {
- public:
- /// Constructor
- WrapArraysInStructs();
-
- /// Destructor
- ~WrapArraysInStructs() 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;
-
- private:
- struct WrappedArrayInfo {
- WrappedArrayInfo();
- WrappedArrayInfo(const WrappedArrayInfo&);
- ~WrappedArrayInfo();
-
- Symbol wrapper_name;
- std::function<const ast::Type*(CloneContext&)> array_type;
-
- operator bool() { return wrapper_name.IsValid(); }
- };
-
- /// WrapArray wraps the fixed-size array type in a new structure (if it hasn't
- /// already been wrapped). WrapArray will recursively wrap arrays-of-arrays.
- /// The new structure will be added to module-scope type declarations of
- /// `ctx.dst`.
- /// @param ctx the CloneContext
- /// @param wrapped_arrays a map of src array type to the wrapped structure
- /// name
- /// @param array the array type
- /// @return the name of the structure that wraps the array, or an invalid
- /// Symbol if this array should not be wrapped
- WrappedArrayInfo WrapArray(
- CloneContext& ctx,
- std::unordered_map<const sem::Array*, WrappedArrayInfo>& wrapped_arrays,
- const sem::Array* array) const;
-};
-
-} // namespace tint::transform
-
-#endif // SRC_TINT_TRANSFORM_WRAP_ARRAYS_IN_STRUCTS_H_
diff --git a/src/tint/transform/wrap_arrays_in_structs_test.cc b/src/tint/transform/wrap_arrays_in_structs_test.cc
deleted file mode 100644
index 7a7a6b3..0000000
--- a/src/tint/transform/wrap_arrays_in_structs_test.cc
+++ /dev/null
@@ -1,422 +0,0 @@
-// Copyright 2021 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/transform/wrap_arrays_in_structs.h"
-
-#include <memory>
-#include <utility>
-
-#include "src/tint/transform/test_helper.h"
-
-namespace tint::transform {
-namespace {
-
-using WrapArraysInStructsTest = TransformTest;
-
-TEST_F(WrapArraysInStructsTest, ShouldRunEmptyModule) {
- auto* src = R"()";
-
- EXPECT_FALSE(ShouldRun<WrapArraysInStructs>(src));
-}
-
-TEST_F(WrapArraysInStructsTest, ShouldRunHasArray) {
- auto* src = R"(
-var<private> arr : array<i32, 4>;
-)";
-
- EXPECT_TRUE(ShouldRun<WrapArraysInStructs>(src));
-}
-
-TEST_F(WrapArraysInStructsTest, EmptyModule) {
- auto* src = R"()";
- auto* expect = src;
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, ArrayAsGlobal) {
- auto* src = R"(
-var<private> arr : array<i32, 4>;
-)";
- auto* expect = R"(
-struct tint_array_wrapper {
- arr : array<i32, 4u>,
-}
-
-var<private> arr : tint_array_wrapper;
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, ArrayAsFunctionVar) {
- auto* src = R"(
-fn f() {
- var arr : array<i32, 4>;
- let x = arr[3];
-}
-)";
- auto* expect = R"(
-struct tint_array_wrapper {
- arr : array<i32, 4u>,
-}
-
-fn f() {
- var arr : tint_array_wrapper;
- let x = arr.arr[3];
-}
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, ArrayAsParam) {
- auto* src = R"(
-fn f(a : array<i32, 4>) -> i32 {
- return a[2];
-}
-)";
- auto* expect = R"(
-struct tint_array_wrapper {
- arr : array<i32, 4u>,
-}
-
-fn f(a : tint_array_wrapper) -> i32 {
- return a.arr[2];
-}
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, ArrayAsReturn) {
- auto* src = R"(
-fn f() -> array<i32, 4> {
- return array<i32, 4>(1, 2, 3, 4);
-}
-)";
- auto* expect = R"(
-struct tint_array_wrapper {
- arr : array<i32, 4u>,
-}
-
-fn f() -> tint_array_wrapper {
- return tint_array_wrapper(array<i32, 4u>(1, 2, 3, 4));
-}
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, ArrayAlias) {
- auto* src = R"(
-type Inner = array<i32, 2>;
-type Array = array<Inner, 2>;
-
-fn f() {
- var arr : Array;
- arr = Array();
- arr = Array(Inner(1, 2), Inner(3, 4));
- let vals : Array = Array(Inner(1, 2), Inner(3, 4));
- arr = vals;
- let x = arr[3];
-}
-)";
- auto* expect = R"(
-struct tint_array_wrapper {
- arr : array<i32, 2u>,
-}
-
-type Inner = tint_array_wrapper;
-
-struct tint_array_wrapper_1 {
- arr : array<tint_array_wrapper, 2u>,
-}
-
-type Array = tint_array_wrapper_1;
-
-fn f() {
- var arr : tint_array_wrapper_1;
- arr = tint_array_wrapper_1(array<tint_array_wrapper, 2u>());
- arr = tint_array_wrapper_1(array<tint_array_wrapper, 2u>(tint_array_wrapper(array<i32, 2u>(1, 2)), tint_array_wrapper(array<i32, 2u>(3, 4))));
- let vals : tint_array_wrapper_1 = tint_array_wrapper_1(array<tint_array_wrapper, 2u>(tint_array_wrapper(array<i32, 2u>(1, 2)), tint_array_wrapper(array<i32, 2u>(3, 4))));
- arr = vals;
- let x = arr.arr[3];
-}
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, ArrayAlias_OutOfOrder) {
- auto* src = R"(
-fn f() {
- var arr : Array;
- arr = Array();
- arr = Array(Inner(1, 2), Inner(3, 4));
- let vals : Array = Array(Inner(1, 2), Inner(3, 4));
- arr = vals;
- let x = arr[3];
-}
-
-type Array = array<Inner, 2>;
-type Inner = array<i32, 2>;
-)";
- auto* expect = R"(
-struct tint_array_wrapper_1 {
- arr : array<i32, 2u>,
-}
-
-struct tint_array_wrapper {
- arr : array<tint_array_wrapper_1, 2u>,
-}
-
-fn f() {
- var arr : tint_array_wrapper;
- arr = tint_array_wrapper(array<tint_array_wrapper_1, 2u>());
- arr = tint_array_wrapper(array<tint_array_wrapper_1, 2u>(tint_array_wrapper_1(array<i32, 2u>(1, 2)), tint_array_wrapper_1(array<i32, 2u>(3, 4))));
- let vals : tint_array_wrapper = tint_array_wrapper(array<tint_array_wrapper_1, 2u>(tint_array_wrapper_1(array<i32, 2u>(1, 2)), tint_array_wrapper_1(array<i32, 2u>(3, 4))));
- arr = vals;
- let x = arr.arr[3];
-}
-
-type Array = tint_array_wrapper;
-
-type Inner = tint_array_wrapper_1;
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, ArraysInStruct) {
- auto* src = R"(
-struct S {
- a : array<i32, 4>,
- b : array<i32, 8>,
- c : array<i32, 4>,
-};
-)";
- auto* expect = R"(
-struct tint_array_wrapper {
- arr : array<i32, 4u>,
-}
-
-struct tint_array_wrapper_1 {
- arr : array<i32, 8u>,
-}
-
-struct S {
- a : tint_array_wrapper,
- b : tint_array_wrapper_1,
- c : tint_array_wrapper,
-}
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, ArraysOfArraysInStruct) {
- auto* src = R"(
-struct S {
- a : array<i32, 4>,
- b : array<array<i32, 4>, 4>,
- c : array<array<array<i32, 4>, 4>, 4>,
-};
-)";
- auto* expect = R"(
-struct tint_array_wrapper {
- arr : array<i32, 4u>,
-}
-
-struct tint_array_wrapper_1 {
- arr : array<tint_array_wrapper, 4u>,
-}
-
-struct tint_array_wrapper_2 {
- arr : array<tint_array_wrapper_1, 4u>,
-}
-
-struct S {
- a : tint_array_wrapper,
- b : tint_array_wrapper_1,
- c : tint_array_wrapper_2,
-}
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, AccessArraysOfArraysInStruct) {
- auto* src = R"(
-struct S {
- a : array<i32, 4>,
- b : array<array<i32, 4>, 4>,
- c : array<array<array<i32, 4>, 4>, 4>,
-};
-
-fn f(s : S) -> i32 {
- return s.a[2] + s.b[1][2] + s.c[3][1][2];
-}
-)";
- auto* expect = R"(
-struct tint_array_wrapper {
- arr : array<i32, 4u>,
-}
-
-struct tint_array_wrapper_1 {
- arr : array<tint_array_wrapper, 4u>,
-}
-
-struct tint_array_wrapper_2 {
- arr : array<tint_array_wrapper_1, 4u>,
-}
-
-struct S {
- a : tint_array_wrapper,
- b : tint_array_wrapper_1,
- c : tint_array_wrapper_2,
-}
-
-fn f(s : S) -> i32 {
- return ((s.a.arr[2] + s.b.arr[1].arr[2]) + s.c.arr[3].arr[1].arr[2]);
-}
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, DeclarationOrder) {
- auto* src = R"(
-type T0 = i32;
-
-type T1 = array<i32, 1>;
-
-type T2 = i32;
-
-fn f1(a : array<i32, 2>) {
-}
-
-type T3 = i32;
-
-fn f2() {
- var v : array<i32, 3>;
-}
-)";
- auto* expect = R"(
-type T0 = i32;
-
-struct tint_array_wrapper {
- arr : array<i32, 1u>,
-}
-
-type T1 = tint_array_wrapper;
-
-type T2 = i32;
-
-struct tint_array_wrapper_1 {
- arr : array<i32, 2u>,
-}
-
-fn f1(a : tint_array_wrapper_1) {
-}
-
-type T3 = i32;
-
-struct tint_array_wrapper_2 {
- arr : array<i32, 3u>,
-}
-
-fn f2() {
- var v : tint_array_wrapper_2;
-}
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(WrapArraysInStructsTest, DeclarationOrder_OutOfOrder) {
- auto* src = R"(
-fn f2() {
- var v : array<i32, 3>;
-}
-
-type T3 = i32;
-
-fn f1(a : array<i32, 2>) {
-}
-
-type T2 = i32;
-
-type T1 = array<i32, 1>;
-
-type T0 = i32;
-)";
- auto* expect = R"(
-struct tint_array_wrapper {
- arr : array<i32, 3u>,
-}
-
-fn f2() {
- var v : tint_array_wrapper;
-}
-
-type T3 = i32;
-
-struct tint_array_wrapper_1 {
- arr : array<i32, 2u>,
-}
-
-fn f1(a : tint_array_wrapper_1) {
-}
-
-type T2 = i32;
-
-struct tint_array_wrapper_2 {
- arr : array<i32, 1u>,
-}
-
-type T1 = tint_array_wrapper_2;
-
-type T0 = i32;
-)";
-
- auto got = Run<WrapArraysInStructs>(src);
-
- EXPECT_EQ(expect, str(got));
-}
-
-} // namespace
-} // namespace tint::transform
diff --git a/src/tint/transform/zero_init_workgroup_memory.cc b/src/tint/transform/zero_init_workgroup_memory.cc
index f56dc61..96395f1 100644
--- a/src/tint/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/transform/zero_init_workgroup_memory.cc
@@ -358,8 +358,8 @@
continue;
}
auto* sem = ctx.src->Sem().Get(expr);
- if (auto c = sem->ConstantValue()) {
- workgroup_size_const *= c.Element<AInt>(0).value;
+ if (auto* c = sem->ConstantValue()) {
+ workgroup_size_const *= c->As<AInt>();
continue;
}
// Constant value could not be found. Build expression instead.
diff --git a/src/tint/utils/block_allocator_test.cc b/src/tint/utils/block_allocator_test.cc
index 600019c..77ea3e3 100644
--- a/src/tint/utils/block_allocator_test.cc
+++ b/src/tint/utils/block_allocator_test.cc
@@ -67,7 +67,7 @@
TEST_F(BlockAllocatorTest, MoveConstruct) {
using Allocator = BlockAllocator<LifetimeCounter>;
- for (size_t n : {0, 1, 10, 16, 20, 32, 50, 64, 100, 256, 300, 512, 500, 512}) {
+ for (size_t n : {0u, 1u, 10u, 16u, 20u, 32u, 50u, 64u, 100u, 256u, 300u, 512u, 500u, 512u}) {
size_t count = 0;
{
Allocator allocator_a;
@@ -87,7 +87,7 @@
TEST_F(BlockAllocatorTest, MoveAssign) {
using Allocator = BlockAllocator<LifetimeCounter>;
- for (size_t n : {0, 1, 10, 16, 20, 32, 50, 64, 100, 256, 300, 512, 500, 512}) {
+ for (size_t n : {0u, 1u, 10u, 16u, 20u, 32u, 50u, 64u, 100u, 256u, 300u, 512u, 500u, 512u}) {
size_t count_a = 0;
size_t count_b = 0;
diff --git a/src/tint/utils/compiler_macros.h b/src/tint/utils/compiler_macros.h
index 34965c6..b3cca3c 100644
--- a/src/tint/utils/compiler_macros.h
+++ b/src/tint/utils/compiler_macros.h
@@ -25,7 +25,11 @@
////////////////////////////////////////////////////////////////////////////////
#define TINT_DISABLE_WARNING_CONSTANT_OVERFLOW __pragma(warning(disable : 4756))
#define TINT_DISABLE_WARNING_MAYBE_UNINITIALIZED /* currently no-op */
+#define TINT_DISABLE_WARNING_NEWLINE_EOF /* currently no-op */
+#define TINT_DISABLE_WARNING_OLD_STYLE_CAST /* currently no-op */
+#define TINT_DISABLE_WARNING_SIGN_CONVERSION /* currently no-op */
#define TINT_DISABLE_WARNING_UNREACHABLE_CODE __pragma(warning(disable : 4702))
+#define TINT_DISABLE_WARNING_WEAK_VTABLES /* currently no-op */
// clang-format off
#define TINT_BEGIN_DISABLE_WARNING(name) \
@@ -42,7 +46,12 @@
////////////////////////////////////////////////////////////////////////////////
#define TINT_DISABLE_WARNING_CONSTANT_OVERFLOW /* currently no-op */
#define TINT_DISABLE_WARNING_MAYBE_UNINITIALIZED /* currently no-op */
+#define TINT_DISABLE_WARNING_NEWLINE_EOF _Pragma("clang diagnostic ignored \"-Wnewline-eof\"")
+#define TINT_DISABLE_WARNING_OLD_STYLE_CAST _Pragma("clang diagnostic ignored \"-Wold-style-cast\"")
+#define TINT_DISABLE_WARNING_SIGN_CONVERSION \
+ _Pragma("clang diagnostic ignored \"-Wsign-conversion\"")
#define TINT_DISABLE_WARNING_UNREACHABLE_CODE /* currently no-op */
+#define TINT_DISABLE_WARNING_WEAK_VTABLES _Pragma("clang diagnostic ignored \"-Wweak-vtables\"")
// clang-format off
#define TINT_BEGIN_DISABLE_WARNING(name) \
@@ -60,7 +69,11 @@
#define TINT_DISABLE_WARNING_CONSTANT_OVERFLOW /* currently no-op */
#define TINT_DISABLE_WARNING_MAYBE_UNINITIALIZED \
_Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+#define TINT_DISABLE_WARNING_NEWLINE_EOF /* currently no-op */
+#define TINT_DISABLE_WARNING_OLD_STYLE_CAST /* currently no-op */
+#define TINT_DISABLE_WARNING_SIGN_CONVERSION /* currently no-op */
#define TINT_DISABLE_WARNING_UNREACHABLE_CODE /* currently no-op */
+#define TINT_DISABLE_WARNING_WEAK_VTABLES /* currently no-op */
// clang-format off
#define TINT_BEGIN_DISABLE_WARNING(name) \
diff --git a/src/tint/writer/append_vector.cc b/src/tint/writer/append_vector.cc
index bc89d1f..c5f184d 100644
--- a/src/tint/writer/append_vector.cc
+++ b/src/tint/writer/append_vector.cc
@@ -59,7 +59,7 @@
<< "unsupported vector element type: " << ty->TypeInfo().name;
return nullptr;
}
- auto* sem = b.create<sem::Expression>(expr, ty, stmt, sem::Constant{},
+ auto* sem = b.create<sem::Expression>(expr, ty, stmt, /* constant_value */ nullptr,
/* has_side_effects */ false);
b.Sem().Add(expr, sem);
return sem;
@@ -135,11 +135,11 @@
auto* scalar_cast_ast = b->Construct(packed_el_ast_ty, scalar_ast);
auto* scalar_cast_target = b->create<sem::TypeConversion>(
packed_el_sem_ty,
- b->create<sem::Parameter>(nullptr, 0, scalar_sem->Type()->UnwrapRef(),
+ b->create<sem::Parameter>(nullptr, 0u, scalar_sem->Type()->UnwrapRef(),
ast::StorageClass::kNone, ast::Access::kUndefined));
auto* scalar_cast_sem = b->create<sem::Call>(
scalar_cast_ast, scalar_cast_target, std::vector<const sem::Expression*>{scalar_sem},
- statement, sem::Constant{}, /* has_side_effects */ false);
+ statement, /* constant_value */ nullptr, /* has_side_effects */ false);
b->Sem().Add(scalar_cast_ast, scalar_cast_sem);
packed.emplace_back(scalar_cast_sem);
} else {
@@ -158,7 +158,7 @@
ast::Access::kUndefined);
}));
auto* constructor_sem = b->create<sem::Call>(constructor_ast, constructor_target, packed,
- statement, sem::Constant{},
+ statement, /* constant_value */ nullptr,
/* has_side_effects */ false);
b->Sem().Add(constructor_ast, constructor_sem);
return constructor_sem;
diff --git a/src/tint/writer/append_vector_test.cc b/src/tint/writer/append_vector_test.cc
index 8169039..2231003 100644
--- a/src/tint/writer/append_vector_test.cc
+++ b/src/tint/writer/append_vector_test.cc
@@ -250,7 +250,7 @@
// AppendVector(vec_12, 3) -> vec3<i32>(vec_12, 3)
TEST_F(AppendVectorTest, Vec2i32Var_i32) {
- Global("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
auto* vec_12 = Expr("vec_12");
auto* scalar_3 = Expr(3_i);
WrapInFunction(vec_12, scalar_3);
@@ -286,7 +286,7 @@
// AppendVector(1, 2, scalar_3) -> vec3<i32>(1, 2, scalar_3)
TEST_F(AppendVectorTest, Vec2i32_i32Var) {
- Global("scalar_3", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("scalar_3", ty.i32(), ast::StorageClass::kPrivate);
auto* scalar_1 = Expr(1_i);
auto* scalar_2 = Expr(2_i);
auto* scalar_3 = Expr("scalar_3");
@@ -327,8 +327,8 @@
// AppendVector(vec_12, scalar_3) -> vec3<i32>(vec_12, scalar_3)
TEST_F(AppendVectorTest, Vec2i32Var_i32Var) {
- Global("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
- Global("scalar_3", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("scalar_3", ty.i32(), ast::StorageClass::kPrivate);
auto* vec_12 = Expr("vec_12");
auto* scalar_3 = Expr("scalar_3");
WrapInFunction(vec_12, scalar_3);
@@ -364,8 +364,8 @@
// AppendVector(vec_12, scalar_3) -> vec3<i32>(vec_12, i32(scalar_3))
TEST_F(AppendVectorTest, Vec2i32Var_f32Var) {
- Global("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
- Global("scalar_3", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("scalar_3", ty.f32(), ast::StorageClass::kPrivate);
auto* vec_12 = Expr("vec_12");
auto* scalar_3 = Expr("scalar_3");
WrapInFunction(vec_12, scalar_3);
@@ -405,8 +405,8 @@
// AppendVector(vec_12, scalar_3) -> vec3<bool>(vec_12, scalar_3)
TEST_F(AppendVectorTest, Vec2boolVar_boolVar) {
- Global("vec_12", ty.vec2<bool>(), ast::StorageClass::kPrivate);
- Global("scalar_3", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("vec_12", ty.vec2<bool>(), ast::StorageClass::kPrivate);
+ GlobalVar("scalar_3", ty.bool_(), ast::StorageClass::kPrivate);
auto* vec_12 = Expr("vec_12");
auto* scalar_3 = Expr("scalar_3");
WrapInFunction(vec_12, scalar_3);
diff --git a/src/tint/writer/flatten_bindings_test.cc b/src/tint/writer/flatten_bindings_test.cc
index 1c516c9..ae01abd 100644
--- a/src/tint/writer/flatten_bindings_test.cc
+++ b/src/tint/writer/flatten_bindings_test.cc
@@ -41,9 +41,9 @@
TEST_F(FlattenBindingsTest, AlreadyFlat) {
ProgramBuilder b;
- b.Global("a", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
- b.Global("b", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 1));
- b.Global("c", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 2));
+ b.GlobalVar("a", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
+ b.GlobalVar("b", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 1));
+ b.GlobalVar("c", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 2));
b.WrapInFunction();
resolver::Resolver resolver(&b);
@@ -57,9 +57,9 @@
TEST_F(FlattenBindingsTest, NotFlat_SingleNamespace) {
ProgramBuilder b;
- b.Global("a", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
- b.Global("b", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(1, 1));
- b.Global("c", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(2, 2));
+ b.GlobalVar("a", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
+ b.GlobalVar("b", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(1, 1));
+ b.GlobalVar("c", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(2, 2));
b.WrapInFunction(b.Expr("a"), b.Expr("b"), b.Expr("c"));
resolver::Resolver resolver(&b);
@@ -83,29 +83,30 @@
ProgramBuilder b;
const size_t num_buffers = 3;
- b.Global("buffer1", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
- b.Global("buffer2", b.ty.i32(), ast::StorageClass::kStorage, b.GroupAndBinding(1, 1));
- b.Global("buffer3", b.ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
- b.GroupAndBinding(2, 2));
+ b.GlobalVar("buffer1", b.ty.i32(), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
+ b.GlobalVar("buffer2", b.ty.i32(), ast::StorageClass::kStorage, b.GroupAndBinding(1, 1));
+ b.GlobalVar("buffer3", b.ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
+ b.GroupAndBinding(2, 2));
const size_t num_samplers = 2;
- b.Global("sampler1", b.ty.sampler(ast::SamplerKind::kSampler), b.GroupAndBinding(3, 3));
- b.Global("sampler2", b.ty.sampler(ast::SamplerKind::kComparisonSampler),
- b.GroupAndBinding(4, 4));
+ b.GlobalVar("sampler1", b.ty.sampler(ast::SamplerKind::kSampler), b.GroupAndBinding(3, 3));
+ b.GlobalVar("sampler2", b.ty.sampler(ast::SamplerKind::kComparisonSampler),
+ b.GroupAndBinding(4, 4));
const size_t num_textures = 6;
- b.Global("texture1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
- b.GroupAndBinding(5, 5));
- b.Global("texture2", b.ty.multisampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
- b.GroupAndBinding(6, 6));
- b.Global("texture3",
- b.ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
- ast::Access::kWrite),
- b.GroupAndBinding(7, 7));
- b.Global("texture4", b.ty.depth_texture(ast::TextureDimension::k2d), b.GroupAndBinding(8, 8));
- b.Global("texture5", b.ty.depth_multisampled_texture(ast::TextureDimension::k2d),
- b.GroupAndBinding(9, 9));
- b.Global("texture6", b.ty.external_texture(), b.GroupAndBinding(10, 10));
+ b.GlobalVar("texture1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
+ b.GroupAndBinding(5, 5));
+ b.GlobalVar("texture2", b.ty.multisampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
+ b.GroupAndBinding(6, 6));
+ b.GlobalVar("texture3",
+ b.ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
+ ast::Access::kWrite),
+ b.GroupAndBinding(7, 7));
+ b.GlobalVar("texture4", b.ty.depth_texture(ast::TextureDimension::k2d),
+ b.GroupAndBinding(8, 8));
+ b.GlobalVar("texture5", b.ty.depth_multisampled_texture(ast::TextureDimension::k2d),
+ b.GroupAndBinding(9, 9));
+ b.GlobalVar("texture6", b.ty.external_texture(), b.GroupAndBinding(10, 10));
b.WrapInFunction(b.Assign(b.Phony(), "buffer1"), b.Assign(b.Phony(), "buffer2"),
b.Assign(b.Phony(), "buffer3"), b.Assign(b.Phony(), "sampler1"),
diff --git a/src/tint/writer/float_to_string_test.cc b/src/tint/writer/float_to_string_test.cc
index 2596be7..b629b50 100644
--- a/src/tint/writer/float_to_string_test.cc
+++ b/src/tint/writer/float_to_string_test.cc
@@ -27,7 +27,7 @@
// - 0 sign if sign is 0, 1 otherwise
// - 'exponent_bits' is placed in the exponent space.
// So, the exponent bias must already be included.
-float MakeFloat(int sign, int biased_exponent, int mantissa) {
+float MakeFloat(uint32_t sign, uint32_t biased_exponent, uint32_t mantissa) {
const uint32_t sign_bit = sign ? 0x80000000u : 0u;
// The binary32 exponent is 8 bits, just below the sign.
const uint32_t exponent_bits = (biased_exponent & 0xffu) << 23;
diff --git a/src/tint/writer/generate_external_texture_bindings_test.cc b/src/tint/writer/generate_external_texture_bindings_test.cc
index d0918c3..292b2ea 100644
--- a/src/tint/writer/generate_external_texture_bindings_test.cc
+++ b/src/tint/writer/generate_external_texture_bindings_test.cc
@@ -37,7 +37,7 @@
TEST_F(GenerateExternalTextureBindingsTest, One) {
ProgramBuilder b;
- b.Global("v0", b.ty.external_texture(), b.GroupAndBinding(0, 0));
+ b.GlobalVar("v0", b.ty.external_texture(), b.GroupAndBinding(0, 0));
b.WrapInFunction();
tint::Program program(std::move(b));
@@ -54,8 +54,8 @@
TEST_F(GenerateExternalTextureBindingsTest, Two_SameGroup) {
ProgramBuilder b;
- b.Global("v0", b.ty.external_texture(), b.GroupAndBinding(0, 0));
- b.Global("v1", b.ty.external_texture(), b.GroupAndBinding(0, 1));
+ b.GlobalVar("v0", b.ty.external_texture(), b.GroupAndBinding(0, 0));
+ b.GlobalVar("v1", b.ty.external_texture(), b.GroupAndBinding(0, 1));
b.WrapInFunction();
tint::Program program(std::move(b));
@@ -78,8 +78,8 @@
TEST_F(GenerateExternalTextureBindingsTest, Two_DifferentGroup) {
ProgramBuilder b;
- b.Global("v0", b.ty.external_texture(), b.GroupAndBinding(0, 0));
- b.Global("v1", b.ty.external_texture(), b.GroupAndBinding(1, 0));
+ b.GlobalVar("v0", b.ty.external_texture(), b.GroupAndBinding(0, 0));
+ b.GlobalVar("v1", b.ty.external_texture(), b.GroupAndBinding(1, 0));
b.WrapInFunction();
tint::Program program(std::move(b));
@@ -102,11 +102,11 @@
TEST_F(GenerateExternalTextureBindingsTest, Two_WithOtherBindingsInSameGroup) {
ProgramBuilder b;
- b.Global("v0", b.ty.i32(), b.GroupAndBinding(0, 0), kUniform);
- b.Global("v1", b.ty.external_texture(), b.GroupAndBinding(0, 1));
- b.Global("v2", b.ty.i32(), b.GroupAndBinding(0, 2), kUniform);
- b.Global("v3", b.ty.external_texture(), b.GroupAndBinding(0, 3));
- b.Global("v4", b.ty.i32(), b.GroupAndBinding(0, 4), kUniform);
+ b.GlobalVar("v0", b.ty.i32(), b.GroupAndBinding(0, 0), kUniform);
+ b.GlobalVar("v1", b.ty.external_texture(), b.GroupAndBinding(0, 1));
+ b.GlobalVar("v2", b.ty.i32(), b.GroupAndBinding(0, 2), kUniform);
+ b.GlobalVar("v3", b.ty.external_texture(), b.GroupAndBinding(0, 3));
+ b.GlobalVar("v4", b.ty.i32(), b.GroupAndBinding(0, 4), kUniform);
b.WrapInFunction();
tint::Program program(std::move(b));
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index 66ff64a..fdf4557 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -58,7 +58,7 @@
#include "src/tint/transform/fold_trivial_single_use_lets.h"
#include "src/tint/transform/loop_to_for_loop.h"
#include "src/tint/transform/manager.h"
-#include "src/tint/transform/promote_initializers_to_const_var.h"
+#include "src/tint/transform/promote_initializers_to_let.h"
#include "src/tint/transform/promote_side_effects_to_decl.h"
#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/renamer.h"
@@ -175,6 +175,8 @@
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
+ polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
+ polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.count_leading_zeros = true;
polyfills.count_trailing_zeros = true;
polyfills.extract_bits = transform::BuiltinPolyfill::Level::kClampParameters;
@@ -226,7 +228,7 @@
options.binding_points, options.access_controls, options.allow_collisions);
manager.Add<transform::BindingRemapper>();
- manager.Add<transform::PromoteInitializersToConstVar>();
+ manager.Add<transform::PromoteInitializersToLet>();
manager.Add<transform::AddEmptyEntryPoint>();
manager.Add<transform::AddSpirvBlockAttribute>();
data.Add<transform::CanonicalizeEntryPointIO::Config>(
@@ -388,11 +390,10 @@
return false;
}
}
- out << "(";
+ ScopedParen sp(out);
if (!EmitExpression(out, expr->expr)) {
return false;
}
- out << ")";
return true;
}
@@ -432,7 +433,7 @@
default:
break;
}
- out << "(";
+ ScopedParen sp(out);
if (!EmitExpression(out, expr->lhs)) {
return false;
}
@@ -440,7 +441,6 @@
if (!EmitExpression(out, expr->rhs)) {
return false;
}
- out << ")";
return true;
}
@@ -594,7 +594,7 @@
return EmitFloatModulo(out, expr);
}
- out << "(";
+ ScopedParen sp(out);
if (!EmitExpression(out, expr->lhs)) {
return false;
}
@@ -670,7 +670,6 @@
return false;
}
- out << ")";
return true;
}
@@ -730,7 +729,8 @@
auto name = builder_.Symbols().NameFor(ident->symbol);
auto caller_sym = ident->symbol;
- out << name << "(";
+ out << name;
+ ScopedParen sp(out);
bool first = true;
for (auto* arg : args) {
@@ -744,7 +744,6 @@
}
}
- out << ")";
return true;
}
@@ -809,7 +808,8 @@
return false;
}
- out << name << "(";
+ out << name;
+ ScopedParen sp(out);
bool first = true;
for (auto* arg : call->Arguments()) {
@@ -823,7 +823,6 @@
}
}
- out << ")";
return true;
}
@@ -833,13 +832,12 @@
if (!EmitType(out, conv->Target(), ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
return false;
}
- out << "(";
+ ScopedParen sp(out);
if (!EmitExpression(out, call->Arguments()[0]->Declaration())) {
return false;
}
- out << ")";
return true;
}
@@ -1183,7 +1181,9 @@
}
}
- out << fn << "(";
+ out << fn;
+ ScopedParen sp(out);
+
if (!EmitExpression(out, expr->args[0])) {
return false;
}
@@ -1191,7 +1191,6 @@
if (!EmitExpression(out, expr->args[1])) {
return false;
}
- out << ")";
return true;
}
@@ -1333,7 +1332,7 @@
const ast::Expression* GeneratorImpl::CreateF32Zero(const sem::Statement* stmt) {
auto* zero = builder_.Expr(0_f);
auto* f32 = builder_.create<sem::F32>();
- auto* sem_zero = builder_.create<sem::Expression>(zero, f32, stmt, sem::Constant{},
+ auto* sem_zero = builder_.create<sem::Expression>(zero, f32, stmt, /* constant_value */ nullptr,
/* has_side_effects */ false);
builder_.Sem().Add(zero, sem_zero);
return zero;
@@ -1350,8 +1349,8 @@
// Returns the argument with the given usage
auto arg = [&](Usage usage) {
- int idx = signature.IndexOf(usage);
- return (idx >= 0) ? arguments[idx] : nullptr;
+ auto idx = signature.IndexOf(usage);
+ return (idx >= 0) ? arguments[static_cast<size_t>(idx)] : nullptr;
};
auto* texture = arg(Usage::kTexture);
@@ -1608,10 +1607,13 @@
switch (builtin->Type()) {
case sem::BuiltinType::kAbs:
case sem::BuiltinType::kAcos:
+ case sem::BuiltinType::kAcosh:
case sem::BuiltinType::kAll:
case sem::BuiltinType::kAny:
case sem::BuiltinType::kAsin:
+ case sem::BuiltinType::kAsinh:
case sem::BuiltinType::kAtan:
+ case sem::BuiltinType::kAtanh:
case sem::BuiltinType::kCeil:
case sem::BuiltinType::kClamp:
case sem::BuiltinType::kCos:
@@ -1769,7 +1771,7 @@
bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) {
if (auto* sem = builder_.Sem().Get(expr)) {
- if (auto constant = sem->ConstantValue()) {
+ if (auto* constant = sem->ConstantValue()) {
return EmitConstant(out, constant);
}
}
@@ -1930,6 +1932,9 @@
},
[&](const ast::Let* let) { return EmitProgramConstVariable(let); },
[&](const ast::Override* override) { return EmitOverride(override); },
+ [&](const ast::Const*) {
+ return true; // Constants are embedded at their use
+ },
[&](Default) {
TINT_ICE(Writer, diagnostics_)
<< "unhandled global variable type " << global->TypeInfo().name;
@@ -2133,7 +2138,7 @@
// Emit the layout(local_size) attributes.
auto wgsize = func_sem->WorkgroupSize();
out << "layout(";
- for (int i = 0; i < 3; i++) {
+ for (size_t i = 0; i < 3; i++) {
if (i > 0) {
out << ", ";
}
@@ -2209,90 +2214,85 @@
return true;
}
-bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant& constant) {
- auto emit_bool = [&](size_t element_idx) {
- out << (constant.Element<AInt>(element_idx) ? "true" : "false");
- return true;
- };
- auto emit_f32 = [&](size_t element_idx) {
- PrintF32(out, static_cast<float>(constant.Element<AFloat>(element_idx)));
- return true;
- };
- auto emit_i32 = [&](size_t element_idx) {
- out << constant.Element<AInt>(element_idx).value;
- return true;
- };
- auto emit_u32 = [&](size_t element_idx) {
- out << constant.Element<AInt>(element_idx).value << "u";
- return true;
- };
- auto emit_vector = [&](const sem::Vector* vec_ty, size_t start, size_t end) {
- if (!EmitType(out, vec_ty, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
- return false;
- }
-
- ScopedParen sp(out);
-
- auto emit_els = [&](auto emit_el) {
- if (constant.AllEqual(start, end)) {
- return emit_el(start);
+bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant* constant) {
+ return Switch(
+ constant->Type(), //
+ [&](const sem::Bool*) {
+ out << (constant->As<AInt>() ? "true" : "false");
+ return true;
+ },
+ [&](const sem::F32*) {
+ PrintF32(out, constant->As<float>());
+ return true;
+ },
+ [&](const sem::I32*) {
+ out << constant->As<AInt>();
+ return true;
+ },
+ [&](const sem::U32*) {
+ out << constant->As<AInt>() << "u";
+ return true;
+ },
+ [&](const sem::Vector* v) {
+ if (!EmitType(out, v, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+ return false;
}
- for (size_t i = start; i < end; i++) {
- if (i > start) {
+
+ ScopedParen sp(out);
+
+ if (constant->AllEqual()) {
+ return EmitConstant(out, constant->Index(0));
+ }
+
+ for (size_t i = 0; i < v->Width(); i++) {
+ if (i > 0) {
out << ", ";
}
- if (!emit_el(i)) {
+ if (!EmitConstant(out, constant->Index(i))) {
return false;
}
}
return true;
- };
-
- return Switch(
- vec_ty->type(), //
- [&](const sem::Bool*) { return emit_els(emit_bool); }, //
- [&](const sem::F32*) { return emit_els(emit_f32); }, //
- [&](const sem::I32*) { return emit_els(emit_i32); }, //
- [&](const sem::U32*) { return emit_els(emit_u32); }, //
- [&](Default) {
- diagnostics_.add_error(diag::System::Writer,
- "unhandled constant vector element type: " +
- builder_.FriendlyName(vec_ty->type()));
- return false;
- });
- };
- auto emit_matrix = [&](const sem::Matrix* m) {
- if (!EmitType(out, constant.Type(), ast::StorageClass::kNone, ast::Access::kUndefined,
- "")) {
- return false;
- }
-
- ScopedParen sp(out);
-
- for (size_t column_idx = 0; column_idx < m->columns(); column_idx++) {
- if (column_idx > 0) {
- out << ", ";
- }
- size_t start = m->rows() * column_idx;
- size_t end = m->rows() * (column_idx + 1);
- if (!emit_vector(m->ColumnType(), start, end)) {
+ },
+ [&](const sem::Matrix* m) {
+ if (!EmitType(out, m, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return false;
}
- }
- return true;
- };
- return Switch(
- constant.Type(), //
- [&](const sem::Bool*) { return emit_bool(0); }, //
- [&](const sem::F32*) { return emit_f32(0); }, //
- [&](const sem::I32*) { return emit_i32(0); }, //
- [&](const sem::U32*) { return emit_u32(0); }, //
- [&](const sem::Vector* v) { return emit_vector(v, 0, constant.ElementCount()); }, //
- [&](const sem::Matrix* m) { return emit_matrix(m); }, //
+
+ ScopedParen sp(out);
+
+ for (size_t column_idx = 0; column_idx < m->columns(); column_idx++) {
+ if (column_idx > 0) {
+ out << ", ";
+ }
+ if (!EmitConstant(out, constant->Index(column_idx))) {
+ return false;
+ }
+ }
+ return true;
+ },
+ [&](const sem::Array* a) {
+ if (!EmitType(out, a, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+ return false;
+ }
+
+ ScopedParen sp(out);
+
+ for (size_t i = 0; i < a->Count(); i++) {
+ if (i > 0) {
+ out << ", ";
+ }
+ if (!EmitConstant(out, constant->Index(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ },
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,
- "unhandled constant type: " + builder_.FriendlyName(constant.Type()));
+ "unhandled constant type: " + builder_.FriendlyName(constant->Type()));
return false;
});
}
@@ -2361,7 +2361,7 @@
return false;
}
bool first = true;
- out << "(";
+ ScopedParen sp(out);
for (auto* member : str->Members()) {
if (!first) {
out << ", ";
@@ -2370,19 +2370,17 @@
}
EmitZeroValue(out, member->Type());
}
- out << ")";
} else if (auto* array = type->As<sem::Array>()) {
if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return false;
}
- out << "(";
+ ScopedParen sp(out);
for (uint32_t i = 0; i < array->Count(); i++) {
if (i != 0) {
out << ", ";
}
EmitZeroValue(out, array->ElemType());
}
- out << ")";
} else {
diagnostics_.add_error(diag::System::Writer, "Invalid type for zero emission: " +
type->FriendlyName(builder_.Symbols()));
@@ -2659,6 +2657,9 @@
v->variable, //
[&](const ast::Var* var) { return EmitVar(var); },
[&](const ast::Let* let) { return EmitLet(let); },
+ [&](const ast::Const*) {
+ return true; // Constants are embedded at their use
+ },
[&](Default) { //
TINT_ICE(Writer, diagnostics_)
<< "unknown variable type: " << v->variable->TypeInfo().name;
@@ -2934,14 +2935,12 @@
out << "-";
break;
}
- out << "(";
+ ScopedParen sp(out);
if (!EmitExpression(out, expr->expr)) {
return false;
}
- out << ")";
-
return true;
}
diff --git a/src/tint/writer/glsl/generator_impl.h b/src/tint/writer/glsl/generator_impl.h
index 5b07fd3..15b7ee1 100644
--- a/src/tint/writer/glsl/generator_impl.h
+++ b/src/tint/writer/glsl/generator_impl.h
@@ -346,7 +346,7 @@
/// @param out the output stream
/// @param constant the constant value to emit
/// @returns true if the constant value was successfully emitted
- bool EmitConstant(std::ostream& out, const sem::Constant& constant);
+ bool EmitConstant(std::ostream& out, const sem::Constant* constant);
/// Handles a literal
/// @param out the output stream
/// @param lit the literal to emit
diff --git a/src/tint/writer/glsl/generator_impl_array_accessor_test.cc b/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
index d28e560..bbf90fe 100644
--- a/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
@@ -22,7 +22,7 @@
using GlslGeneratorImplTest_Expression = TestHelper;
TEST_F(GlslGeneratorImplTest_Expression, IndexAccessor) {
- Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
+ GlobalVar("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
auto* expr = IndexAccessor("ary", 5_i);
WrapInFunction(expr);
diff --git a/src/tint/writer/glsl/generator_impl_assign_test.cc b/src/tint/writer/glsl/generator_impl_assign_test.cc
index fbd9f62..84b6b30 100644
--- a/src/tint/writer/glsl/generator_impl_assign_test.cc
+++ b/src/tint/writer/glsl/generator_impl_assign_test.cc
@@ -20,8 +20,8 @@
using GlslGeneratorImplTest_Assign = TestHelper;
TEST_F(GlslGeneratorImplTest_Assign, Emit_Assign) {
- Global("lhs", ty.i32(), ast::StorageClass::kPrivate);
- Global("rhs", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("lhs", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("rhs", ty.i32(), ast::StorageClass::kPrivate);
auto* assign = Assign("lhs", "rhs");
WrapInFunction(assign);
diff --git a/src/tint/writer/glsl/generator_impl_binary_test.cc b/src/tint/writer/glsl/generator_impl_binary_test.cc
index 0d019a9..b529255 100644
--- a/src/tint/writer/glsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/glsl/generator_impl_binary_test.cc
@@ -43,8 +43,8 @@
return;
}
- Global("left", ty.f32(), ast::StorageClass::kPrivate);
- Global("right", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("left", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("right", ty.f32(), ast::StorageClass::kPrivate);
auto* left = Expr("left");
auto* right = Expr("right");
@@ -62,8 +62,8 @@
TEST_P(GlslBinaryTest, Emit_u32) {
auto params = GetParam();
- Global("left", ty.u32(), ast::StorageClass::kPrivate);
- Global("right", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("left", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("right", ty.u32(), ast::StorageClass::kPrivate);
auto* left = Expr("left");
auto* right = Expr("right");
@@ -86,8 +86,8 @@
return;
}
- Global("left", ty.i32(), ast::StorageClass::kPrivate);
- Global("right", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("left", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("right", ty.i32(), ast::StorageClass::kPrivate);
auto* left = Expr("left");
auto* right = Expr("right");
@@ -153,7 +153,7 @@
}
TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixScalar) {
- Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* lhs = Expr("mat");
auto* rhs = Expr(1_f);
@@ -168,7 +168,7 @@
}
TEST_F(GlslGeneratorImplTest_Binary, Multiply_ScalarMatrix) {
- Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* lhs = Expr(1_f);
auto* rhs = Expr("mat");
@@ -183,7 +183,7 @@
}
TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixVector) {
- Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* lhs = Expr("mat");
auto* rhs = vec3<f32>(1_f, 1_f, 1_f);
@@ -198,7 +198,7 @@
}
TEST_F(GlslGeneratorImplTest_Binary, Multiply_VectorMatrix) {
- Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* lhs = vec3<f32>(1_f, 1_f, 1_f);
auto* rhs = Expr("mat");
@@ -213,8 +213,8 @@
}
TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixMatrix) {
- Global("lhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
- Global("rhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("lhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("rhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("lhs"), Expr("rhs"));
WrapInFunction(expr);
@@ -227,8 +227,8 @@
}
TEST_F(GlslGeneratorImplTest_Binary, Logical_And) {
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b"));
WrapInFunction(expr);
@@ -246,8 +246,8 @@
}
TEST_F(GlslGeneratorImplTest_Binary, ModF32) {
- Global("a", ty.f32(), ast::StorageClass::kPrivate);
- Global("b", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
WrapInFunction(expr);
@@ -260,8 +260,8 @@
}
TEST_F(GlslGeneratorImplTest_Binary, ModVec3F32) {
- Global("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
- Global("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
WrapInFunction(expr);
@@ -275,10 +275,10 @@
TEST_F(GlslGeneratorImplTest_Binary, Logical_Multi) {
// (a && b) || (c || d)
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
- Global("d", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(
ast::BinaryOp::kLogicalOr,
@@ -307,8 +307,8 @@
}
TEST_F(GlslGeneratorImplTest_Binary, Logical_Or) {
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("b"));
WrapInFunction(expr);
@@ -334,9 +334,9 @@
// return 3i;
// }
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr =
If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
@@ -371,9 +371,9 @@
TEST_F(GlslGeneratorImplTest_Binary, Return_WithLogical) {
// return (a && b) || c;
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = Return(create<ast::BinaryExpression>(
ast::BinaryOp::kLogicalOr,
@@ -399,10 +399,10 @@
TEST_F(GlslGeneratorImplTest_Binary, Assign_WithLogical) {
// a = (b || c) && d;
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
- Global("d", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr =
Assign(Expr("a"),
@@ -430,9 +430,9 @@
TEST_F(GlslGeneratorImplTest_Binary, Decl_WithLogical) {
// var a : bool = (b && c) || d;
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
- Global("d", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
auto* var =
Var("a", ty.bool_(), ast::StorageClass::kNone,
@@ -469,10 +469,10 @@
Param(Sym(), ty.bool_()),
},
ty.void_(), ast::StatementList{}, ast::AttributeList{});
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
- Global("d", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
ast::ExpressionList params;
params.push_back(
diff --git a/src/tint/writer/glsl/generator_impl_builtin_test.cc b/src/tint/writer/glsl/generator_impl_builtin_test.cc
index f7572b2..c753293 100644
--- a/src/tint/writer/glsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/glsl/generator_impl_builtin_test.cc
@@ -153,13 +153,13 @@
TEST_P(GlslBuiltinTest, Emit) {
auto param = GetParam();
- Global("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
- Global("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
- Global("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
- Global("i2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
- Global("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
- Global("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
- Global("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
+ GlobalVar("i2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
+ GlobalVar("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
auto* call = GenerateCall(param.builtin, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled builtin";
@@ -242,8 +242,8 @@
TEST_F(GlslGeneratorImplTest_Builtin, Builtin_Call) {
auto* call = Call("dot", "param1", "param2");
- Global("param1", ty.vec3<f32>(), ast::StorageClass::kPrivate);
- Global("param2", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.vec3<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@@ -584,7 +584,7 @@
TEST_F(GlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
auto* call = Call("pack4x8snorm", "p1");
- Global("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -602,7 +602,7 @@
TEST_F(GlslGeneratorImplTest_Builtin, Pack4x8Unorm) {
auto* call = Call("pack4x8unorm", "p1");
- Global("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -620,7 +620,7 @@
TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Snorm) {
auto* call = Call("pack2x16snorm", "p1");
- Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -638,7 +638,7 @@
TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Unorm) {
auto* call = Call("pack2x16unorm", "p1");
- Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -656,7 +656,7 @@
TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Float) {
auto* call = Call("pack2x16float", "p1");
- Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -674,7 +674,7 @@
TEST_F(GlslGeneratorImplTest_Builtin, Unpack4x8Snorm) {
auto* call = Call("unpack4x8snorm", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -692,7 +692,7 @@
TEST_F(GlslGeneratorImplTest_Builtin, Unpack4x8Unorm) {
auto* call = Call("unpack4x8unorm", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -710,7 +710,7 @@
TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Snorm) {
auto* call = Call("unpack2x16snorm", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -728,7 +728,7 @@
TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Unorm) {
auto* call = Call("unpack2x16unorm", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -746,7 +746,7 @@
TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Float) {
auto* call = Call("unpack2x16float", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -803,7 +803,7 @@
}
TEST_F(GlslGeneratorImplTest_Builtin, DotI32) {
- Global("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(Call("dot", "v", "v")));
GeneratorImpl& gen = SanitizeAndBuild();
@@ -831,9 +831,9 @@
TEST_F(GlslGeneratorImplTest_Builtin, FMA) {
auto* call = Call("fma", "a", "b", "c");
- Global("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
- Global("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
- Global("c", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.vec3<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@@ -846,7 +846,7 @@
}
TEST_F(GlslGeneratorImplTest_Builtin, DotU32) {
- Global("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+ GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(Call("dot", "v", "v")));
GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/glsl/generator_impl_call_test.cc b/src/tint/writer/glsl/generator_impl_call_test.cc
index c8a1de2..d1866ea 100644
--- a/src/tint/writer/glsl/generator_impl_call_test.cc
+++ b/src/tint/writer/glsl/generator_impl_call_test.cc
@@ -42,8 +42,8 @@
Param(Sym(), ty.f32()),
},
ty.f32(), {Return(1.23_f)});
- Global("param1", ty.f32(), ast::StorageClass::kPrivate);
- Global("param2", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
auto* call = Call("my_func", "param1", "param2");
WrapInFunction(call);
@@ -62,8 +62,8 @@
Param(Sym(), ty.f32()),
},
ty.void_(), ast::StatementList{}, ast::AttributeList{});
- Global("param1", ty.f32(), ast::StorageClass::kPrivate);
- Global("param2", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
auto* call = CallStmt(Call("my_func", "param1", "param2"));
WrapInFunction(call);
diff --git a/src/tint/writer/glsl/generator_impl_constructor_test.cc b/src/tint/writer/glsl/generator_impl_constructor_test.cc
index e70ecaf..9a937e8 100644
--- a/src/tint/writer/glsl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_constructor_test.cc
@@ -189,8 +189,7 @@
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
- EXPECT_THAT(gen.result(), HasSubstr("vec3[3](vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f),"
- " vec3(0.0f, 0.0f, 0.0f))"));
+ EXPECT_THAT(gen.result(), HasSubstr("vec3[3](vec3(0.0f), vec3(0.0f), vec3(0.0f))"));
}
TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct) {
diff --git a/src/tint/writer/glsl/generator_impl_function_test.cc b/src/tint/writer/glsl/generator_impl_function_test.cc
index 13e32fc..a70e238 100644
--- a/src/tint/writer/glsl/generator_impl_function_test.cc
+++ b/src/tint/writer/glsl/generator_impl_function_test.cc
@@ -349,11 +349,11 @@
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_Uniform) {
auto* ubo_ty = Structure("UBO", {Member("coord", ty.vec4<f32>())});
- auto* ubo = Global("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ auto* ubo = GlobalVar("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
Func("sub_func",
{
@@ -403,11 +403,11 @@
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_UniformStruct) {
auto* s = Structure("Uniforms", {Member("coord", ty.vec4<f32>())});
- Global("uniforms", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("uniforms", ty.Of(s), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
@@ -448,11 +448,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
@@ -498,11 +498,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
@@ -549,11 +549,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
Func("frag_main", {}, ty.void_(),
{
@@ -597,11 +597,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
Func("frag_main", {}, ty.void_(),
{
@@ -641,11 +641,11 @@
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
auto* s = Structure("S", {Member("x", ty.f32())});
- Global("coord", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
Func("sub_func", {Param("param", ty.f32())}, ty.f32(),
{
@@ -690,11 +690,11 @@
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_StorageBuffer) {
auto* s = Structure("S", {Member("x", ty.f32())});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
Func("sub_func", {Param("param", ty.f32())}, ty.f32(),
{
@@ -820,9 +820,6 @@
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
-const int width = 2;
-const int height = 3;
-const int depth = 4;
layout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;
void main() {
return;
@@ -922,11 +919,11 @@
auto* s = Structure("Data", {Member("d", ty.f32())});
- Global("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
diff --git a/src/tint/writer/glsl/generator_impl_identifier_test.cc b/src/tint/writer/glsl/generator_impl_identifier_test.cc
index 396c261..ff9bc88 100644
--- a/src/tint/writer/glsl/generator_impl_identifier_test.cc
+++ b/src/tint/writer/glsl/generator_impl_identifier_test.cc
@@ -20,7 +20,7 @@
using GlslGeneratorImplTest_Identifier = TestHelper;
TEST_F(GlslGeneratorImplTest_Identifier, EmitIdentifierExpression) {
- Global("foo", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("foo", ty.i32(), ast::StorageClass::kPrivate);
auto* i = Expr("foo");
WrapInFunction(i);
diff --git a/src/tint/writer/glsl/generator_impl_if_test.cc b/src/tint/writer/glsl/generator_impl_if_test.cc
index 4b0b7bb..82dc307 100644
--- a/src/tint/writer/glsl/generator_impl_if_test.cc
+++ b/src/tint/writer/glsl/generator_impl_if_test.cc
@@ -20,7 +20,7 @@
using GlslGeneratorImplTest_If = TestHelper;
TEST_F(GlslGeneratorImplTest_If, Emit_If) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* cond = Expr("cond");
auto* body = Block(Return());
@@ -38,8 +38,8 @@
}
TEST_F(GlslGeneratorImplTest_If, Emit_IfWithElseIf) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
- Global("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* else_cond = Expr("else_cond");
auto* else_body = Block(Return());
@@ -65,7 +65,7 @@
}
TEST_F(GlslGeneratorImplTest_If, Emit_IfWithElse) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* else_body = Block(Return());
@@ -88,8 +88,8 @@
}
TEST_F(GlslGeneratorImplTest_If, Emit_IfWithMultiple) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
- Global("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* else_cond = Expr("else_cond");
diff --git a/src/tint/writer/glsl/generator_impl_import_test.cc b/src/tint/writer/glsl/generator_impl_import_test.cc
index 2843f98..9e988f1 100644
--- a/src/tint/writer/glsl/generator_impl_import_test.cc
+++ b/src/tint/writer/glsl/generator_impl_import_test.cc
@@ -256,7 +256,7 @@
testing::Values(GlslImportData{"clamp", "clamp"}));
TEST_F(GlslGeneratorImplTest_Import, GlslImportData_Determinant) {
- Global("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("determinant", "var");
WrapInFunction(expr);
diff --git a/src/tint/writer/glsl/generator_impl_loop_test.cc b/src/tint/writer/glsl/generator_impl_loop_test.cc
index ec9219a..9da50f0 100644
--- a/src/tint/writer/glsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/glsl/generator_impl_loop_test.cc
@@ -66,8 +66,8 @@
TEST_F(GlslGeneratorImplTest_Loop, Emit_LoopNestedWithContinuing) {
Func("a_statement", {}, ty.void_(), {});
- Global("lhs", ty.f32(), ast::StorageClass::kPrivate);
- Global("rhs", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("lhs", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
auto* body = Block(create<ast::DiscardStatement>());
auto* continuing = Block(CallStmt(Call("a_statement")));
@@ -112,7 +112,7 @@
// }
// }
- Global("rhs", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4_f))), //
Decl(Var("other", ty.f32())), //
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 fcfa9df..875d211 100644
--- a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
@@ -91,11 +91,11 @@
auto* s = b.Structure("Data", members);
- b.Global("data", b.ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- b.create<ast::BindingAttribute>(0),
- b.create<ast::GroupAttribute>(1),
- });
+ b.GlobalVar("data", b.ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ b.create<ast::BindingAttribute>(0u),
+ b.create<ast::GroupAttribute>(1u),
+ });
}
void SetupFunction(ast::StatementList statements) {
@@ -115,7 +115,7 @@
TEST_F(GlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
auto* s = Structure("Data", {Member("mem", ty.f32())});
- Global("str", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("str", "mem");
WrapInFunction(Var("expr", ty.f32(), ast::StorageClass::kNone, expr));
diff --git a/src/tint/writer/glsl/generator_impl_module_constant_test.cc b/src/tint/writer/glsl/generator_impl_module_constant_test.cc
index a97d4cd..b483511 100644
--- a/src/tint/writer/glsl/generator_impl_module_constant_test.cc
+++ b/src/tint/writer/glsl/generator_impl_module_constant_test.cc
@@ -22,7 +22,7 @@
using GlslGeneratorImplTest_ModuleConstant = TestHelper;
-TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalLet) {
auto* var = Let("pos", ty.array<f32, 3>(), array<f32, 3>(1_f, 2_f, 3_f));
WrapInFunction(Decl(var));
@@ -32,7 +32,216 @@
EXPECT_EQ(gen.result(), "const float pos[3] = float[3](1.0f, 2.0f, 3.0f);\n");
}
-TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant) {
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AInt) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ int l = 1;
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AFloat) {
+ auto* var = GlobalConst("G", nullptr, Expr(1._a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ float l = 1.0f;
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_i32) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_i));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ int l = 1;
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_u32) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_u));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ uint l = 1u;
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_f32) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ float l = 1.0f;
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AInt) {
+ auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ ivec3 l = ivec3(1, 2, 3);
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AFloat) {
+ auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ vec3 l = vec3(1.0f, 2.0f, 3.0f);
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_f32) {
+ auto* var = GlobalConst("G", nullptr, vec3<f32>(1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ vec3 l = vec3(1.0f, 2.0f, 3.0f);
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_AFloat) {
+ auto* var = GlobalConst("G", nullptr,
+ Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ mat2x3 l = mat2x3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f));
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_f32) {
+ auto* var = GlobalConst("G", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ mat2x3 l = mat2x3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f));
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_f32) {
+ auto* var = GlobalConst("G", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ float l[3] = float[3](1.0f, 2.0f, 3.0f);
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_vec2_bool) {
+ auto* var = GlobalConst("G", nullptr,
+ Construct(ty.array(ty.vec2<bool>(), 3_u), //
+ vec2<bool>(true, false), //
+ vec2<bool>(false, true), //
+ vec2<bool>(true, true)));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ bvec2 l[3] = bvec2[3](bvec2(true, false), bvec2(false, true), bvec2(true));
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_Override) {
auto* var = Override("pos", ty.f32(), Expr(3_f),
ast::AttributeList{
Id(23),
@@ -48,7 +257,7 @@
)");
}
-TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoConstructor) {
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_Override_NoConstructor) {
auto* var = Override("pos", ty.f32(), nullptr,
ast::AttributeList{
Id(23),
@@ -64,7 +273,7 @@
)");
}
-TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoId) {
+TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_Override_NoId) {
auto* a = Override("a", ty.f32(), Expr(3_f),
ast::AttributeList{
Id(0),
diff --git a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
index f2b57c7..ae1b0ba 100644
--- a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
@@ -26,11 +26,11 @@
TEST_F(GlslSanitizerTest, Call_ArrayLength) {
auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
{
@@ -69,11 +69,11 @@
Member(0, "z", ty.f32()),
Member(4, "a", ty.array<f32>(4)),
});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
{
@@ -111,11 +111,11 @@
TEST_F(GlslSanitizerTest, Call_ArrayLength_ViaLets) {
auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
auto* p = Let("p", nullptr, AddressOf("b"));
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
@@ -156,12 +156,11 @@
TEST_F(GlslSanitizerTest, PromoteArrayInitializerToConstVar) {
auto* array_init = array<i32, 4>(1_i, 2_i, 3_i, 4_i);
- auto* array_index = IndexAccessor(array_init, 3_i);
- auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
Func("main", {}, ty.void_(),
{
- Decl(pos),
+ Decl(Var("idx", nullptr, Expr(3_i))),
+ Decl(Var("pos", ty.i32(), IndexAccessor(array_init, "idx"))),
},
{
Stage(ast::PipelineStage::kFragment),
@@ -176,8 +175,9 @@
precision mediump float;
void tint_symbol() {
+ int idx = 3;
int tint_symbol_1[4] = int[4](1, 2, 3, 4);
- int pos = tint_symbol_1[3];
+ int pos = tint_symbol_1[idx];
}
void main() {
diff --git a/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc b/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
index a12fbbc..7a13b66 100644
--- a/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
@@ -35,11 +35,11 @@
ctx->Member("dewey", ctx->ty.f32(), {ctx->MemberAlign(256)}),
ctx->Member("louie", ctx->ty.f32(), {ctx->MemberAlign(256)}),
});
- ctx->Global("nephews", ctx->ty.Of(nephews), ast::StorageClass::kStorage,
- ast::AttributeList{
- ctx->create<ast::BindingAttribute>(0),
- ctx->create<ast::GroupAttribute>(0),
- });
+ ctx->GlobalVar("nephews", ctx->ty.Of(nephews), ast::StorageClass::kStorage,
+ ast::AttributeList{
+ ctx->create<ast::BindingAttribute>(0u),
+ ctx->create<ast::GroupAttribute>(0u),
+ });
}
TEST_F(GlslGeneratorImplTest_StorageBuffer, Align) {
diff --git a/src/tint/writer/glsl/generator_impl_switch_test.cc b/src/tint/writer/glsl/generator_impl_switch_test.cc
index 1cc42fb..c8957be 100644
--- a/src/tint/writer/glsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/glsl/generator_impl_switch_test.cc
@@ -22,7 +22,7 @@
using GlslGeneratorImplTest_Switch = TestHelper;
TEST_F(GlslGeneratorImplTest_Switch, Emit_Switch) {
- Global("cond", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.i32(), ast::StorageClass::kPrivate);
auto* def_body = Block(create<ast::BreakStatement>());
auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
diff --git a/src/tint/writer/glsl/generator_impl_test.cc b/src/tint/writer/glsl/generator_impl_test.cc
index 70e5c0b..3dbf601 100644
--- a/src/tint/writer/glsl/generator_impl_test.cc
+++ b/src/tint/writer/glsl/generator_impl_test.cc
@@ -57,12 +57,12 @@
}
TEST_F(GlslGeneratorImplTest, GenerateSampleIndexES) {
- Global("gl_SampleID", ty.i32(),
- ast::AttributeList{
- Builtin(ast::Builtin::kSampleIndex),
- Disable(ast::DisabledValidation::kIgnoreStorageClass),
- },
- ast::StorageClass::kInput);
+ GlobalVar("gl_SampleID", ty.i32(),
+ ast::AttributeList{
+ Builtin(ast::Builtin::kSampleIndex),
+ Disable(ast::DisabledValidation::kIgnoreStorageClass),
+ },
+ ast::StorageClass::kInput);
Func("my_func", {}, ty.i32(),
{
Return(Expr("gl_SampleID")),
@@ -82,12 +82,12 @@
}
TEST_F(GlslGeneratorImplTest, GenerateSampleIndexDesktop) {
- Global("gl_SampleID", ty.i32(),
- ast::AttributeList{
- Builtin(ast::Builtin::kSampleIndex),
- Disable(ast::DisabledValidation::kIgnoreStorageClass),
- },
- ast::StorageClass::kInput);
+ GlobalVar("gl_SampleID", ty.i32(),
+ ast::AttributeList{
+ Builtin(ast::Builtin::kSampleIndex),
+ Disable(ast::DisabledValidation::kIgnoreStorageClass),
+ },
+ ast::StorageClass::kInput);
Func("my_func", {}, ty.i32(),
{
Return(Expr("gl_SampleID")),
diff --git a/src/tint/writer/glsl/generator_impl_type_test.cc b/src/tint/writer/glsl/generator_impl_type_test.cc
index b7daee2..acf28ff 100644
--- a/src/tint/writer/glsl/generator_impl_type_test.cc
+++ b/src/tint/writer/glsl/generator_impl_type_test.cc
@@ -33,7 +33,7 @@
TEST_F(GlslGeneratorImplTest_Type, EmitType_Array) {
auto* arr = ty.array<bool, 4>();
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -46,7 +46,7 @@
TEST_F(GlslGeneratorImplTest_Type, EmitType_ArrayOfArray) {
auto* arr = ty.array(ty.array<bool, 4>(), 5_u);
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -59,7 +59,7 @@
TEST_F(GlslGeneratorImplTest_Type, EmitType_ArrayOfArrayOfArray) {
auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5_u), 6_u);
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -72,7 +72,7 @@
TEST_F(GlslGeneratorImplTest_Type, EmitType_Array_WithoutName) {
auto* arr = ty.array<bool, 4>();
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -134,7 +134,7 @@
Member("a", ty.i32()),
Member("b", ty.f32()),
});
- Global("g", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -154,7 +154,7 @@
Member("a", ty.i32()),
Member("b", ty.f32()),
});
- Global("g", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -170,7 +170,7 @@
Member("double", ty.i32()),
Member("float", ty.f32()),
});
- Global("g", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
GeneratorImpl& gen = SanitizeAndBuild();
@@ -187,7 +187,7 @@
Member("a", ty.i32(), {MemberOffset(0)}),
Member("b", ty.f32(), {MemberOffset(8)}),
});
- Global("g", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -270,11 +270,11 @@
auto* t = ty.depth_texture(params.dim);
- Global("tex", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("tex", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
{Stage(ast::PipelineStage::kFragment)});
@@ -297,11 +297,11 @@
TEST_F(GlslDepthMultisampledTexturesTest, Emit) {
auto* t = ty.depth_multisampled_texture(ast::TextureDimension::k2d);
- Global("tex", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("tex", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
{Stage(ast::PipelineStage::kFragment)});
@@ -340,11 +340,11 @@
}
auto* t = ty.sampled_texture(params.dim, datatype);
- Global("tex", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("tex", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
{Stage(ast::PipelineStage::kFragment)});
@@ -474,11 +474,11 @@
auto* t = ty.storage_texture(params.dim, params.imgfmt, ast::Access::kWrite);
- Global("tex", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("tex", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
{Stage(ast::PipelineStage::kFragment)});
diff --git a/src/tint/writer/glsl/generator_impl_unary_op_test.cc b/src/tint/writer/glsl/generator_impl_unary_op_test.cc
index 0e318fc..22012c8 100644
--- a/src/tint/writer/glsl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/glsl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
using GlslUnaryOpTest = TestHelper;
TEST_F(GlslUnaryOpTest, AddressOf) {
- Global("expr", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.f32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
WrapInFunction(op);
@@ -32,7 +32,7 @@
}
TEST_F(GlslUnaryOpTest, Complement) {
- Global("expr", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.u32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
WrapInFunction(op);
@@ -44,7 +44,7 @@
}
TEST_F(GlslUnaryOpTest, Indirection) {
- Global("G", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("G", ty.f32(), ast::StorageClass::kPrivate);
auto* p =
Let("expr", nullptr, create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
@@ -58,7 +58,7 @@
}
TEST_F(GlslUnaryOpTest, Not) {
- Global("expr", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.bool_(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
WrapInFunction(op);
@@ -70,7 +70,7 @@
}
TEST_F(GlslUnaryOpTest, Negation) {
- Global("expr", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.i32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
WrapInFunction(op);
diff --git a/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc b/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
index 8709b3d..8e653b5 100644
--- a/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
@@ -24,7 +24,7 @@
TEST_F(GlslGeneratorImplTest_UniformBuffer, Simple) {
auto* simple = Structure("Simple", {Member("member", ty.f32())});
- Global("simple", ty.Of(simple), ast::StorageClass::kUniform, GroupAndBinding(0, 0));
+ GlobalVar("simple", ty.Of(simple), ast::StorageClass::kUniform, GroupAndBinding(0, 0));
GeneratorImpl& gen = Build();
@@ -44,7 +44,7 @@
TEST_F(GlslGeneratorImplTest_UniformBuffer, Simple_Desktop) {
auto* simple = Structure("Simple", {Member("member", ty.f32())});
- Global("simple", ty.Of(simple), ast::StorageClass::kUniform, GroupAndBinding(0, 0));
+ GlobalVar("simple", ty.Of(simple), ast::StorageClass::kUniform, GroupAndBinding(0, 0));
GeneratorImpl& gen = Build(Version(Version::Standard::kDesktop, 4, 4));
diff --git a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
index 5d95bc6..daa664a 100644
--- a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
@@ -16,6 +16,8 @@
#include "src/tint/ast/variable_decl_statement.h"
#include "src/tint/writer/glsl/test_helper.h"
+using namespace tint::number_suffixes; // NOLINT
+
namespace tint::writer::glsl {
namespace {
@@ -36,7 +38,7 @@
EXPECT_EQ(gen.result(), " float a = 0.0f;\n");
}
-TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Let) {
auto* var = Let("a", ty.f32(), Construct(ty.f32()));
auto* stmt = Decl(var);
WrapInFunction(stmt);
@@ -49,6 +51,228 @@
EXPECT_EQ(gen.result(), " float a = 0.0f;\n");
}
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
+ auto* var = Const("a", ty.f32(), Construct(ty.f32()));
+ auto* stmt = Decl(var);
+ WrapInFunction(stmt);
+
+ GeneratorImpl& gen = Build();
+
+ gen.increment_indent();
+
+ ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
+ EXPECT_EQ(gen.result(), ""); // Not a mistake - 'const' is inlined
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AInt) {
+ auto* C = Const("C", nullptr, Expr(1_a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ int l = 1;
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AFloat) {
+ auto* C = Const("C", nullptr, Expr(1._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ float l = 1.0f;
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_i32) {
+ auto* C = Const("C", nullptr, Expr(1_i));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ int l = 1;
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_u32) {
+ auto* C = Const("C", nullptr, Expr(1_u));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ uint l = 1u;
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_f32) {
+ auto* C = Const("C", nullptr, Expr(1_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ float l = 1.0f;
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AInt) {
+ auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ ivec3 l = ivec3(1, 2, 3);
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AFloat) {
+ auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ vec3 l = vec3(1.0f, 2.0f, 3.0f);
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_f32) {
+ auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ vec3 l = vec3(1.0f, 2.0f, 3.0f);
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
+ auto* C =
+ Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ mat2x3 l = mat2x3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f));
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_f32) {
+ auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ mat2x3 l = mat2x3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f));
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_f32) {
+ auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ float l[3] = float[3](1.0f, 2.0f, 3.0f);
+}
+
+)");
+}
+
+TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
+ auto* C = Const("C", nullptr,
+ Construct(ty.array(ty.vec2<bool>(), 3_u), //
+ vec2<bool>(true, false), //
+ vec2<bool>(false, true), //
+ vec2<bool>(true, true)));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#version 310 es
+
+void f() {
+ bvec2 l[3] = bvec2[3](bvec2(true, false), bvec2(false, true), bvec2(true));
+}
+
+)");
+}
+
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Array) {
auto* var = Var("a", ty.array<f32, 5>());
@@ -64,7 +288,7 @@
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
- Global("a", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
WrapInFunction(Expr("a"));
@@ -76,19 +300,6 @@
EXPECT_THAT(gen.result(), HasSubstr(" float a = 0.0f;\n"));
}
-TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initializer_Private) {
- Global("initializer", ty.f32(), ast::StorageClass::kPrivate);
- Global("a", ty.f32(), ast::StorageClass::kPrivate, Expr("initializer"));
-
- WrapInFunction(Expr("a"));
-
- GeneratorImpl& gen = Build();
-
- ASSERT_TRUE(gen.Generate()) << gen.error();
- EXPECT_THAT(gen.result(), HasSubstr(R"(float a = initializer;
-)"));
-}
-
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initializer_ZeroVec) {
auto* var = Var("a", ty.vec3<f32>(), ast::StorageClass::kNone, vec3<f32>());
diff --git a/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc b/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
index faa675d..1d96441 100644
--- a/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
+++ b/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
@@ -27,7 +27,7 @@
using GlslGeneratorImplTest_WorkgroupVar = TestHelper;
TEST_F(GlslGeneratorImplTest_WorkgroupVar, Basic) {
- Global("wg", ty.f32(), ast::StorageClass::kWorkgroup);
+ GlobalVar("wg", ty.f32(), ast::StorageClass::kWorkgroup);
Func("main", {}, ty.void_(), {Assign("wg", 1.2_f)},
{
@@ -43,7 +43,7 @@
TEST_F(GlslGeneratorImplTest_WorkgroupVar, Aliased) {
auto* alias = Alias("F32", ty.f32());
- Global("wg", ty.Of(alias), ast::StorageClass::kWorkgroup);
+ GlobalVar("wg", ty.Of(alias), ast::StorageClass::kWorkgroup);
Func("main", {}, ty.void_(), {Assign("wg", 1.2_f)},
{
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index 3dfb74f..b307c8d 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -60,7 +60,7 @@
#include "src/tint/transform/loop_to_for_loop.h"
#include "src/tint/transform/manager.h"
#include "src/tint/transform/num_workgroups_from_uniform.h"
-#include "src/tint/transform/promote_initializers_to_const_var.h"
+#include "src/tint/transform/promote_initializers_to_let.h"
#include "src/tint/transform/promote_side_effects_to_decl.h"
#include "src/tint/transform/remove_continue_in_switch.h"
#include "src/tint/transform/remove_phonies.h"
@@ -158,6 +158,9 @@
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
+ polyfills.acosh = transform::BuiltinPolyfill::Level::kFull;
+ polyfills.asinh = true;
+ polyfills.atanh = transform::BuiltinPolyfill::Level::kFull;
// TODO(crbug.com/tint/1449): Some of these can map to HLSL's `firstbitlow`
// and `firstbithigh`.
polyfills.count_leading_zeros = true;
@@ -231,7 +234,7 @@
// DecomposeMemoryAccess special-cases the arrayLength() intrinsic, which
// will be transformed by CalculateArrayLength
manager.Add<transform::CalculateArrayLength>();
- manager.Add<transform::PromoteInitializersToConstVar>();
+ manager.Add<transform::PromoteInitializersToLet>();
manager.Add<transform::RemoveContinueInSwitch>();
@@ -612,8 +615,7 @@
if (auto* mat = TypeOf(lhs_sub_access->object)->UnwrapRef()->As<sem::Matrix>()) {
auto* rhs_col_idx_sem = builder_.Sem().Get(lhs_access->index);
auto* rhs_row_idx_sem = builder_.Sem().Get(lhs_sub_access->index);
- if (!rhs_col_idx_sem->ConstantValue().IsValid() ||
- !rhs_row_idx_sem->ConstantValue().IsValid()) {
+ if (!rhs_col_idx_sem->ConstantValue() || !rhs_row_idx_sem->ConstantValue()) {
return EmitDynamicMatrixScalarAssignment(stmt, mat);
}
}
@@ -623,7 +625,7 @@
const auto* lhs_access_type = TypeOf(lhs_access->object)->UnwrapRef();
if (auto* mat = lhs_access_type->As<sem::Matrix>()) {
auto* lhs_index_sem = builder_.Sem().Get(lhs_access->index);
- if (!lhs_index_sem->ConstantValue().IsValid()) {
+ if (!lhs_index_sem->ConstantValue()) {
return EmitDynamicMatrixVectorAssignment(stmt, mat);
}
}
@@ -631,7 +633,7 @@
// indices
if (auto* vec = lhs_access_type->As<sem::Vector>()) {
auto* rhs_sem = builder_.Sem().Get(lhs_access->index);
- if (!rhs_sem->ConstantValue().IsValid()) {
+ if (!rhs_sem->ConstantValue()) {
return EmitDynamicVectorAssignment(stmt, vec);
}
}
@@ -651,28 +653,30 @@
bool GeneratorImpl::EmitExpressionOrOneIfZero(std::ostream& out, const ast::Expression* expr) {
// For constants, replace literal 0 with 1.
- if (const auto& val = builder_.Sem().Get(expr)->ConstantValue()) {
- if (!val.AnyZero()) {
+ if (const auto* val = builder_.Sem().Get(expr)->ConstantValue()) {
+ if (!val->AnyZero()) {
return EmitExpression(out, expr);
}
- if (val.Type()->IsAnyOf<sem::I32, sem::U32>()) {
- return EmitValue(out, val.Type(), 1);
+ auto* ty = val->Type();
+
+ if (ty->IsAnyOf<sem::I32, sem::U32>()) {
+ return EmitValue(out, ty, 1);
}
- if (auto* vec = val.Type()->As<sem::Vector>()) {
+ if (auto* vec = ty->As<sem::Vector>()) {
auto* elem_ty = vec->type();
- if (!EmitType(out, val.Type(), ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+ if (!EmitType(out, ty, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return false;
}
out << "(";
- for (size_t i = 0; i < val.ElementCount(); ++i) {
+ for (size_t i = 0; i < vec->Width(); ++i) {
if (i != 0) {
out << ", ";
}
- auto s = val.Element<AInt>(i).value;
+ auto s = val->Index(i)->As<AInt>();
if (!EmitValue(out, elem_ty, (s == 0) ? 1 : static_cast<int>(s))) {
return false;
}
@@ -1110,52 +1114,13 @@
return EmitZeroValue(out, type);
}
- if (auto* mat = call->Type()->As<sem::Matrix>()) {
- if (ctor->Parameters().size() == 1) {
- // Matrix constructor with single scalar.
- auto fn = utils::GetOrCreate(matrix_scalar_ctors_, mat, [&]() -> std::string {
- TextBuffer b;
- TINT_DEFER(helpers_.Append(b));
-
- auto name = UniqueIdentifier("build_mat" + std::to_string(mat->columns()) + "x" +
- std::to_string(mat->rows()));
- {
- auto l = line(&b);
- if (!EmitType(l, mat, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
- return "";
- }
- l << " " << name << "(";
- if (!EmitType(l, mat->type(), ast::StorageClass::kNone, ast::Access::kUndefined,
- "")) {
- return "";
- }
- l << " value) {";
- }
- {
- ScopedIndent si(&b);
- auto l = line(&b);
- l << "return ";
- if (!EmitType(l, mat, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
- return "";
- }
- l << "(";
- for (uint32_t i = 0; i < mat->columns() * mat->rows(); i++) {
- l << ((i > 0) ? ", value" : "value");
- }
- l << ");";
- }
- line(&b) << "}";
- return name;
- });
- if (fn.empty()) {
- return false;
- }
- out << fn << "(";
- if (!EmitExpression(out, call->Arguments()[0]->Declaration())) {
- return false;
- }
- out << ")";
- return true;
+ // Single parameter matrix initializers must be identity constructor.
+ // It could also be conversions between f16 and f32 matrix when f16 is properly supported.
+ if (type->Is<sem::Matrix>() && call->Arguments().size() == 1) {
+ if (!ctor->Parameters()[0]->Type()->UnwrapRef()->is_float_matrix()) {
+ TINT_UNREACHABLE(Writer, diagnostics_)
+ << "found a single-parameter matrix constructor that is not identity constructor";
+ return false;
}
}
@@ -1217,9 +1182,9 @@
// If true, use scalar_offset_value, otherwise use scalar_offset_expr
bool scalar_offset_constant = false;
- if (auto val = offset_arg->ConstantValue()) {
- TINT_ASSERT(Writer, val.Type()->Is<sem::U32>());
- scalar_offset_value = static_cast<uint32_t>(val.Element<AInt>(0).value);
+ if (auto* val = offset_arg->ConstantValue()) {
+ TINT_ASSERT(Writer, val->Type()->Is<sem::U32>());
+ scalar_offset_value = static_cast<uint32_t>(std::get<AInt>(val->Value()));
scalar_offset_value /= 4; // bytes -> scalar index
scalar_offset_constant = true;
}
@@ -1779,8 +1744,8 @@
{ // T compare_value = <compare_value>;
auto pre = line();
- if (!EmitTypeAndName(pre, TypeOf(compare_value), ast::StorageClass::kNone,
- ast::Access::kUndefined, compare)) {
+ if (!EmitTypeAndName(pre, TypeOf(compare_value)->UnwrapRef(),
+ ast::StorageClass::kNone, ast::Access::kUndefined, compare)) {
return false;
}
pre << " = ";
@@ -2143,7 +2108,7 @@
// Returns the argument with the given usage
auto arg = [&](Usage usage) {
int idx = signature.IndexOf(usage);
- return (idx >= 0) ? arguments[idx] : nullptr;
+ return (idx >= 0) ? arguments[static_cast<size_t>(idx)] : nullptr;
};
auto* texture = arg(Usage::kTexture);
@@ -2373,7 +2338,7 @@
case sem::BuiltinType::kTextureGather:
out << ".Gather";
if (builtin->Parameters()[0]->Usage() == sem::ParameterUsage::kComponent) {
- switch (call->Arguments()[0]->ConstantValue().Element<AInt>(0).value) {
+ switch (call->Arguments()[0]->ConstantValue()->As<AInt>()) {
case 0:
out << "Red";
break;
@@ -2420,8 +2385,9 @@
auto* i32 = builder_.create<sem::I32>();
auto* zero = builder_.Expr(0_i);
auto* stmt = builder_.Sem().Get(vector)->Stmt();
- builder_.Sem().Add(zero, builder_.create<sem::Expression>(zero, i32, stmt, sem::Constant{},
- /* has_side_effects */ false));
+ builder_.Sem().Add(
+ zero, builder_.create<sem::Expression>(zero, i32, stmt, /* constant_value */ nullptr,
+ /* has_side_effects */ false));
auto* packed = AppendVector(&builder_, vector, zero);
return EmitExpression(out, packed->Declaration());
};
@@ -2650,7 +2616,7 @@
bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) {
if (auto* sem = builder_.Sem().Get(expr)) {
- if (auto constant = sem->ConstantValue()) {
+ if (auto* constant = sem->ConstantValue()) {
return EmitConstant(out, constant);
}
}
@@ -2882,8 +2848,10 @@
return false;
}
},
- [&](const ast::Let* let) { return EmitProgramConstVariable(let); },
[&](const ast::Override* override) { return EmitOverride(override); },
+ [&](const ast::Const*) {
+ return true; // Constants are embedded at their use
+ },
[&](Default) {
TINT_ICE(Writer, diagnostics_)
<< "unhandled global variable type " << global->TypeInfo().name;
@@ -3073,7 +3041,7 @@
// Emit the workgroup_size attribute.
auto wgsize = func_sem->WorkgroupSize();
out << "[numthreads(";
- for (int i = 0; i < 3; i++) {
+ for (size_t i = 0; i < 3; i++) {
if (i > 0) {
out << ", ";
}
@@ -3143,107 +3111,101 @@
return true;
}
-bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant& constant) {
- auto emit_bool = [&](size_t element_idx) {
- out << (constant.Element<AInt>(element_idx) ? "true" : "false");
- return true;
- };
- auto emit_f32 = [&](size_t element_idx) {
- PrintF32(out, static_cast<float>(constant.Element<AFloat>(element_idx)));
- return true;
- };
- auto emit_i32 = [&](size_t element_idx) {
- out << constant.Element<AInt>(element_idx).value;
- return true;
- };
- auto emit_u32 = [&](size_t element_idx) {
- out << constant.Element<AInt>(element_idx).value << "u";
- return true;
- };
- auto emit_vector = [&](const sem::Vector* vec_ty, size_t start, size_t end) {
- if (constant.AllEqual(start, end)) {
- {
- ScopedParen sp(out);
- bool ok = Switch(
- vec_ty->type(), //
- [&](const sem::Bool*) { return emit_bool(start); }, //
- [&](const sem::F32*) { return emit_f32(start); }, //
- [&](const sem::I32*) { return emit_i32(start); }, //
- [&](const sem::U32*) { return emit_u32(start); } //
- );
- if (!ok) {
- return false;
- }
- }
- out << ".";
- for (size_t i = start; i < end; i++) {
- out << "x";
- }
+bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant* constant) {
+ return Switch(
+ constant->Type(), //
+ [&](const sem::Bool*) {
+ out << (constant->As<AInt>() ? "true" : "false");
return true;
- }
+ },
+ [&](const sem::F32*) {
+ PrintF32(out, constant->As<float>());
+ return true;
+ },
+ [&](const sem::I32*) {
+ out << constant->As<AInt>();
+ return true;
+ },
+ [&](const sem::U32*) {
+ out << constant->As<AInt>() << "u";
+ return true;
+ },
+ [&](const sem::Vector* v) {
+ if (constant->AllEqual()) {
+ {
+ ScopedParen sp(out);
+ if (!EmitConstant(out, constant->Index(0))) {
+ return false;
+ }
+ }
+ out << ".";
+ for (size_t i = 0; i < v->Width(); i++) {
+ out << "x";
+ }
+ return true;
+ }
- if (!EmitType(out, vec_ty, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
- return false;
- }
+ if (!EmitType(out, v, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+ return false;
+ }
- ScopedParen sp(out);
+ ScopedParen sp(out);
- auto emit_els = [&](auto emit_el) {
- for (size_t i = start; i < end; i++) {
- if (i > start) {
+ for (size_t i = 0; i < v->Width(); i++) {
+ if (i > 0) {
out << ", ";
}
- if (!emit_el(i)) {
+ if (!EmitConstant(out, constant->Index(i))) {
return false;
}
}
return true;
- };
- return Switch(
- vec_ty->type(), //
- [&](const sem::Bool*) { return emit_els(emit_bool); }, //
- [&](const sem::F32*) { return emit_els(emit_f32); }, //
- [&](const sem::I32*) { return emit_els(emit_i32); }, //
- [&](const sem::U32*) { return emit_els(emit_u32); }, //
- [&](Default) {
- diagnostics_.add_error(diag::System::Writer,
- "unhandled constant vector element type: " +
- builder_.FriendlyName(vec_ty->type()));
- return false;
- });
- };
- auto emit_matrix = [&](const sem::Matrix* m) {
- if (!EmitType(out, constant.Type(), ast::StorageClass::kNone, ast::Access::kUndefined,
- "")) {
- return false;
- }
-
- ScopedParen sp(out);
-
- for (size_t column_idx = 0; column_idx < m->columns(); column_idx++) {
- if (column_idx > 0) {
- out << ", ";
- }
- size_t start = m->rows() * column_idx;
- size_t end = m->rows() * (column_idx + 1);
- if (!emit_vector(m->ColumnType(), start, end)) {
+ },
+ [&](const sem::Matrix* m) {
+ if (!EmitType(out, m, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return false;
}
- }
- return true;
- };
- return Switch(
- constant.Type(), //
- [&](const sem::Bool*) { return emit_bool(0); }, //
- [&](const sem::F32*) { return emit_f32(0); }, //
- [&](const sem::I32*) { return emit_i32(0); }, //
- [&](const sem::U32*) { return emit_u32(0); }, //
- [&](const sem::Vector* v) { return emit_vector(v, 0, constant.ElementCount()); }, //
- [&](const sem::Matrix* m) { return emit_matrix(m); },
+
+ ScopedParen sp(out);
+
+ for (size_t i = 0; i < m->columns(); i++) {
+ if (i > 0) {
+ out << ", ";
+ }
+ if (!EmitConstant(out, constant->Index(i))) {
+ return false;
+ }
+ }
+ return true;
+ },
+ [&](const sem::Array* a) {
+ if (constant->AllZero()) {
+ out << "(";
+ if (!EmitType(out, a, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+ return false;
+ }
+ out << ")0";
+ return true;
+ }
+
+ out << "{";
+ TINT_DEFER(out << "}");
+
+ for (size_t i = 0; i < a->Count(); i++) {
+ if (i > 0) {
+ out << ", ";
+ }
+ if (!EmitConstant(out, constant->Index(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ },
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,
- "unhandled constant type: " + builder_.FriendlyName(constant.Type()));
+ "unhandled constant type: " + builder_.FriendlyName(constant->Type()));
return false;
});
}
@@ -3618,6 +3580,9 @@
v->variable, //
[&](const ast::Var* var) { return EmitVar(var); },
[&](const ast::Let* let) { return EmitLet(let); },
+ [&](const ast::Const*) {
+ return true; // Constants are embedded at their use
+ },
[&](Default) { //
TINT_ICE(Writer, diagnostics_)
<< "unknown variable type: " << v->variable->TypeInfo().name;
@@ -3728,9 +3693,8 @@
while (auto* arr = base_type->As<sem::Array>()) {
if (arr->IsRuntimeSized()) {
TINT_ICE(Writer, diagnostics_)
- << "Runtime arrays may only exist in storage buffers, which "
- "should "
- "have been transformed into a ByteAddressBuffer";
+ << "Runtime arrays may only exist in storage buffers, which should have "
+ "been transformed into a ByteAddressBuffer";
return false;
}
sizes.push_back(arr->Count());
@@ -4074,25 +4038,6 @@
return true;
}
-bool GeneratorImpl::EmitProgramConstVariable(const ast::Let* let) {
- auto* sem = builder_.Sem().Get(let);
- auto* type = sem->Type();
-
- auto out = line();
- out << "static const ";
- if (!EmitTypeAndName(out, type, ast::StorageClass::kNone, ast::Access::kUndefined,
- builder_.Symbols().NameFor(let->symbol))) {
- return false;
- }
- out << " = ";
- if (!EmitExpression(out, let->constructor)) {
- return false;
- }
- out << ";";
-
- return true;
-}
-
bool GeneratorImpl::EmitOverride(const ast::Override* override) {
auto* sem = builder_.Sem().Get(override);
auto* type = sem->Type();
diff --git a/src/tint/writer/hlsl/generator_impl.h b/src/tint/writer/hlsl/generator_impl.h
index 485b779..bf2debe 100644
--- a/src/tint/writer/hlsl/generator_impl.h
+++ b/src/tint/writer/hlsl/generator_impl.h
@@ -93,7 +93,8 @@
/// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully
bool EmitAssign(const ast::AssignmentStatement* stmt);
- /// Emits code such that if `expr` is zero, it emits one, else `expr`
+ /// Emits code such that if `expr` is zero, it emits one, else `expr`.
+ /// Used to avoid divide-by-zeros by substituting constant zeros with ones.
/// @param out the output of the expression stream
/// @param expr the expression
/// @returns true if the expression was emitted, false otherwise
@@ -342,7 +343,7 @@
/// @param out the output stream
/// @param constant the constant value to emit
/// @returns true if the constant value was successfully emitted
- bool EmitConstant(std::ostream& out, const sem::Constant& constant);
+ bool EmitConstant(std::ostream& out, const sem::Constant* constant);
/// Handles a literal
/// @param out the output stream
/// @param lit the literal to emit
@@ -448,10 +449,6 @@
/// @param let the variable to generate
/// @returns true if the variable was emitted
bool EmitLet(const ast::Let* let);
- /// Handles generating a module-scope 'let' declaration
- /// @param let the 'let' to emit
- /// @returns true if the variable was emitted
- bool EmitProgramConstVariable(const ast::Let* let);
/// Handles generating a module-scope 'override' declaration
/// @param override the 'override' to emit
/// @returns true if the variable was emitted
diff --git a/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
index bbdeb10..dfa3d67 100644
--- a/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
@@ -22,7 +22,7 @@
using HlslGeneratorImplTest_Expression = TestHelper;
TEST_F(HlslGeneratorImplTest_Expression, IndexAccessor) {
- Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
+ GlobalVar("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
auto* expr = IndexAccessor("ary", 5_i);
WrapInFunction(expr);
diff --git a/src/tint/writer/hlsl/generator_impl_assign_test.cc b/src/tint/writer/hlsl/generator_impl_assign_test.cc
index c69cbdf..57e65a9 100644
--- a/src/tint/writer/hlsl/generator_impl_assign_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_assign_test.cc
@@ -41,7 +41,7 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_ConstantIndex) {
+TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_LetIndex) {
Func("fn", {}, ty.void_(),
{
Decl(Var("lhs", ty.vec3<f32>())),
@@ -54,10 +54,35 @@
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(),
- R"(void fn() {
+ R"(void set_float3(inout float3 vec, int idx, float val) {
+ vec = (idx.xxx == int3(0, 1, 2)) ? val.xxx : vec;
+}
+
+void fn() {
float3 lhs = float3(0.0f, 0.0f, 0.0f);
float rhs = 0.0f;
const uint index = 0u;
+ set_float3(lhs, index, rhs);
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_ConstIndex) {
+ Func("fn", {}, ty.void_(),
+ {
+ Decl(Var("lhs", ty.vec3<f32>())),
+ Decl(Var("rhs", ty.f32())),
+ Decl(Const("index", ty.u32(), Expr(0_u))),
+ Assign(IndexAccessor("lhs", "index"), "rhs"),
+ });
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate());
+ EXPECT_EQ(gen.result(),
+ R"(void fn() {
+ float3 lhs = float3(0.0f, 0.0f, 0.0f);
+ float rhs = 0.0f;
lhs[0u] = rhs;
}
)");
@@ -89,7 +114,7 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_ConstantIndex) {
+TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_LetIndex) {
Func("fn", {}, ty.void_(),
{
Decl(Var("lhs", ty.mat4x2<f32>())),
@@ -102,10 +127,40 @@
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(),
- R"(void fn() {
+ R"(void set_vector_float4x2(inout float4x2 mat, int col, float2 val) {
+ switch (col) {
+ case 0: mat[0] = val; break;
+ case 1: mat[1] = val; break;
+ case 2: mat[2] = val; break;
+ case 3: mat[3] = val; break;
+ }
+}
+
+void fn() {
float4x2 lhs = float4x2(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
float2 rhs = float2(0.0f, 0.0f);
const uint index = 0u;
+ set_vector_float4x2(lhs, index, rhs);
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_ConstIndex) {
+ Func("fn", {}, ty.void_(),
+ {
+ Decl(Var("lhs", ty.mat4x2<f32>())),
+ Decl(Var("rhs", ty.vec2<f32>())),
+ Decl(Const("index", ty.u32(), Expr(0_u))),
+ Assign(IndexAccessor("lhs", "index"), "rhs"),
+ });
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate());
+ EXPECT_EQ(gen.result(),
+ R"(void fn() {
+ float4x2 lhs = float4x2(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
+ float2 rhs = float2(0.0f, 0.0f);
lhs[0u] = rhs;
}
)");
@@ -142,7 +197,7 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_ConstantIndex) {
+TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_LetIndex) {
Func("fn", {}, ty.void_(),
{
Decl(Var("lhs", ty.mat4x2<f32>())),
@@ -155,10 +210,48 @@
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(),
- R"(void fn() {
+ R"(void set_scalar_float4x2(inout float4x2 mat, int col, int row, float val) {
+ switch (col) {
+ case 0:
+ mat[0] = (row.xx == int2(0, 1)) ? val.xx : mat[0];
+ break;
+ case 1:
+ mat[1] = (row.xx == int2(0, 1)) ? val.xx : mat[1];
+ break;
+ case 2:
+ mat[2] = (row.xx == int2(0, 1)) ? val.xx : mat[2];
+ break;
+ case 3:
+ mat[3] = (row.xx == int2(0, 1)) ? val.xx : mat[3];
+ break;
+ }
+}
+
+void fn() {
float4x2 lhs = float4x2(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
float rhs = 0.0f;
const uint index = 0u;
+ set_scalar_float4x2(lhs, index, index, rhs);
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_ConstIndex) {
+ Func("fn", {}, ty.void_(),
+ {
+ Decl(Var("lhs", ty.mat4x2<f32>())),
+ Decl(Var("rhs", ty.f32())),
+ Decl(Const("index", ty.u32(), Expr(0_u))),
+ Assign(IndexAccessor(IndexAccessor("lhs", "index"), "index"), "rhs"),
+ });
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate());
+ EXPECT_EQ(gen.result(),
+ R"(void fn() {
+ float4x2 lhs = float4x2(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
+ float rhs = 0.0f;
lhs[0u][0u] = rhs;
}
)");
diff --git a/src/tint/writer/hlsl/generator_impl_binary_test.cc b/src/tint/writer/hlsl/generator_impl_binary_test.cc
index 5825536..b5e47f7 100644
--- a/src/tint/writer/hlsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_binary_test.cc
@@ -50,8 +50,8 @@
return;
}
- Global("left", ty.f32(), ast::StorageClass::kPrivate);
- Global("right", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("left", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("right", ty.f32(), ast::StorageClass::kPrivate);
auto* left = Expr("left");
auto* right = Expr("right");
@@ -73,8 +73,8 @@
return;
}
- Global("left", ty.u32(), ast::StorageClass::kPrivate);
- Global("right", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("left", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("right", ty.u32(), ast::StorageClass::kPrivate);
auto* left = Expr("left");
auto* right = Expr("right");
@@ -101,8 +101,8 @@
return;
}
- Global("left", ty.i32(), ast::StorageClass::kPrivate);
- Global("right", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("left", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("right", ty.i32(), ast::StorageClass::kPrivate);
auto* left = Expr("left");
auto* right = Expr("right");
@@ -171,7 +171,7 @@
}
TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixScalar) {
- Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* lhs = Expr("mat");
auto* rhs = Expr(1_f);
@@ -186,7 +186,7 @@
}
TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarMatrix) {
- Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* lhs = Expr(1_f);
auto* rhs = Expr("mat");
@@ -201,7 +201,7 @@
}
TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixVector) {
- Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* lhs = Expr("mat");
auto* rhs = vec3<f32>(1_f, 1_f, 1_f);
@@ -216,7 +216,7 @@
}
TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorMatrix) {
- Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* lhs = vec3<f32>(1_f, 1_f, 1_f);
auto* rhs = Expr("mat");
@@ -231,8 +231,8 @@
}
TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixMatrix) {
- Global("lhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
- Global("rhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("lhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("rhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("lhs"), Expr("rhs"));
WrapInFunction(expr);
@@ -245,8 +245,8 @@
}
TEST_F(HlslGeneratorImplTest_Binary, Logical_And) {
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b"));
WrapInFunction(expr);
@@ -265,10 +265,10 @@
TEST_F(HlslGeneratorImplTest_Binary, Logical_Multi) {
// (a && b) || (c || d)
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
- Global("d", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(
ast::BinaryOp::kLogicalOr,
@@ -297,8 +297,8 @@
}
TEST_F(HlslGeneratorImplTest_Binary, Logical_Or) {
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("b"));
WrapInFunction(expr);
@@ -324,9 +324,9 @@
// return 3i;
// }
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr =
If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
@@ -361,9 +361,9 @@
TEST_F(HlslGeneratorImplTest_Binary, Return_WithLogical) {
// return (a && b) || c;
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = Return(create<ast::BinaryExpression>(
ast::BinaryOp::kLogicalOr,
@@ -389,10 +389,10 @@
TEST_F(HlslGeneratorImplTest_Binary, Assign_WithLogical) {
// a = (b || c) && d;
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
- Global("d", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr =
Assign(Expr("a"),
@@ -420,9 +420,9 @@
TEST_F(HlslGeneratorImplTest_Binary, Decl_WithLogical) {
// var a : bool = (b && c) || d;
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
- Global("d", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
auto* var =
Var("a", ty.bool_(), ast::StorageClass::kNone,
@@ -459,10 +459,10 @@
Param(Sym(), ty.bool_()),
},
ty.void_(), ast::StatementList{}, ast::AttributeList{});
- Global("a", ty.bool_(), ast::StorageClass::kPrivate);
- Global("b", ty.bool_(), ast::StorageClass::kPrivate);
- Global("c", ty.bool_(), ast::StorageClass::kPrivate);
- Global("d", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
ast::ExpressionList params;
params.push_back(
diff --git a/src/tint/writer/hlsl/generator_impl_builtin_test.cc b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
index c497e51..d008ab8 100644
--- a/src/tint/writer/hlsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
@@ -152,13 +152,13 @@
TEST_P(HlslBuiltinTest, Emit) {
auto param = GetParam();
- Global("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
- Global("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
- Global("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
- Global("i2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
- Global("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
- Global("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
- Global("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
+ GlobalVar("i2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
+ GlobalVar("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
auto* call = GenerateCall(param.builtin, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled builtin";
@@ -241,8 +241,8 @@
TEST_F(HlslGeneratorImplTest_Builtin, Builtin_Call) {
auto* call = Call("dot", "param1", "param2");
- Global("param1", ty.vec3<f32>(), ast::StorageClass::kPrivate);
- Global("param2", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.vec3<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@@ -466,7 +466,7 @@
TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
auto* call = Call("pack4x8snorm", "p1");
- Global("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -488,7 +488,7 @@
TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Unorm) {
auto* call = Call("pack4x8unorm", "p1");
- Global("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -510,7 +510,7 @@
TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Snorm) {
auto* call = Call("pack2x16snorm", "p1");
- Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -532,7 +532,7 @@
TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Unorm) {
auto* call = Call("pack2x16unorm", "p1");
- Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -554,7 +554,7 @@
TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Float) {
auto* call = Call("pack2x16float", "p1");
- Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -576,7 +576,7 @@
TEST_F(HlslGeneratorImplTest_Builtin, Unpack4x8Snorm) {
auto* call = Call("unpack4x8snorm", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -599,7 +599,7 @@
TEST_F(HlslGeneratorImplTest_Builtin, Unpack4x8Unorm) {
auto* call = Call("unpack4x8unorm", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -622,7 +622,7 @@
TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Snorm) {
auto* call = Call("unpack2x16snorm", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -645,7 +645,7 @@
TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Unorm) {
auto* call = Call("unpack2x16unorm", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -668,7 +668,7 @@
TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Float) {
auto* call = Call("unpack2x16float", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_call_test.cc b/src/tint/writer/hlsl/generator_impl_call_test.cc
index b72b0eb..fc41a81 100644
--- a/src/tint/writer/hlsl/generator_impl_call_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_call_test.cc
@@ -42,8 +42,8 @@
Param(Sym(), ty.f32()),
},
ty.f32(), {Return(1.23_f)});
- Global("param1", ty.f32(), ast::StorageClass::kPrivate);
- Global("param2", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
auto* call = Call("my_func", "param1", "param2");
WrapInFunction(call);
@@ -62,8 +62,8 @@
Param(Sym(), ty.f32()),
},
ty.void_(), ast::StatementList{}, ast::AttributeList{});
- Global("param1", ty.f32(), ast::StorageClass::kPrivate);
- Global("param2", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
auto* call = CallStmt(Call("my_func", "param1", "param2"));
WrapInFunction(call);
diff --git a/src/tint/writer/hlsl/generator_impl_case_test.cc b/src/tint/writer/hlsl/generator_impl_case_test.cc
index ee3acfc..5c7e427 100644
--- a/src/tint/writer/hlsl/generator_impl_case_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_case_test.cc
@@ -99,7 +99,7 @@
gen.increment_indent();
- ASSERT_TRUE(gen.EmitCase(s, 0_i)) << gen.error();
+ ASSERT_TRUE(gen.EmitCase(s, 0u)) << gen.error();
EXPECT_EQ(gen.result(), R"( default: {
break;
}
diff --git a/src/tint/writer/hlsl/generator_impl_constructor_test.cc b/src/tint/writer/hlsl/generator_impl_constructor_test.cc
index 700d94b..6a1d696 100644
--- a/src/tint/writer/hlsl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_constructor_test.cc
@@ -223,6 +223,24 @@
EXPECT_THAT(gen.result(), HasSubstr("float2x3 tint_symbol = float2x3((0.0f).xxx, (0.0f).xxx)"));
}
+TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Identity) {
+ // fn f() {
+ // var m_1: mat4x4<f32> = mat4x4<f32>();
+ // var m_2: mat4x4<f32> = mat4x4<f32>(m_1);
+ // }
+
+ auto* m_1 = Var("m_1", ty.mat4x4(ty.f32()), mat4x4<f32>());
+ auto* m_2 = Var("m_2", ty.mat4x4(ty.f32()), mat4x4<f32>(m_1));
+
+ WrapInFunction(m_1, m_2);
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_THAT(gen.result(), HasSubstr("float4x4 m_2 = float4x4(m_1);"));
+}
+
TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Array) {
WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1_f, 2_f, 3_f),
vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
diff --git a/src/tint/writer/hlsl/generator_impl_function_test.cc b/src/tint/writer/hlsl/generator_impl_function_test.cc
index dac42d0..85647a5 100644
--- a/src/tint/writer/hlsl/generator_impl_function_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_function_test.cc
@@ -346,11 +346,11 @@
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_Uniform) {
auto* ubo_ty = Structure("UBO", {Member("coord", ty.vec4<f32>())});
- auto* ubo = Global("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ auto* ubo = GlobalVar("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
Func("sub_func",
{
@@ -393,11 +393,11 @@
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_UniformStruct) {
auto* s = Structure("Uniforms", {Member("coord", ty.vec4<f32>())});
- Global("uniforms", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("uniforms", ty.Of(s), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
@@ -431,11 +431,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
@@ -467,11 +467,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
@@ -503,11 +503,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
Func("frag_main", {}, ty.void_(),
{
@@ -537,11 +537,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
Func("frag_main", {}, ty.void_(),
{
@@ -567,11 +567,11 @@
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
auto* s = Structure("S", {Member("x", ty.f32())});
- Global("coord", ty.Of(s), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
Func("sub_func",
{
@@ -613,11 +613,11 @@
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_StorageBuffer) {
auto* s = Structure("S", {Member("x", ty.f32())});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(1),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(1u),
+ });
Func("sub_func",
{
@@ -718,11 +718,7 @@
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
- EXPECT_EQ(gen.result(), R"(static const int width = 2;
-static const int height = 3;
-static const int depth = 4;
-
-[numthreads(2, 3, 4)]
+ EXPECT_EQ(gen.result(), R"([numthreads(2, 3, 4)]
void main() {
return;
}
@@ -863,11 +859,11 @@
auto* s = Structure("Data", {Member("d", ty.f32())});
- Global("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
diff --git a/src/tint/writer/hlsl/generator_impl_identifier_test.cc b/src/tint/writer/hlsl/generator_impl_identifier_test.cc
index d982e1e..d4b645f 100644
--- a/src/tint/writer/hlsl/generator_impl_identifier_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_identifier_test.cc
@@ -20,7 +20,7 @@
using HlslGeneratorImplTest_Identifier = TestHelper;
TEST_F(HlslGeneratorImplTest_Identifier, EmitIdentifierExpression) {
- Global("foo", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("foo", ty.i32(), ast::StorageClass::kPrivate);
auto* i = Expr("foo");
WrapInFunction(i);
diff --git a/src/tint/writer/hlsl/generator_impl_if_test.cc b/src/tint/writer/hlsl/generator_impl_if_test.cc
index 1668d71..3195a06 100644
--- a/src/tint/writer/hlsl/generator_impl_if_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_if_test.cc
@@ -20,7 +20,7 @@
using HlslGeneratorImplTest_If = TestHelper;
TEST_F(HlslGeneratorImplTest_If, Emit_If) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* cond = Expr("cond");
auto* body = Block(Return());
@@ -38,8 +38,8 @@
}
TEST_F(HlslGeneratorImplTest_If, Emit_IfWithElseIf) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
- Global("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* else_cond = Expr("else_cond");
auto* else_body = Block(Return());
@@ -65,7 +65,7 @@
}
TEST_F(HlslGeneratorImplTest_If, Emit_IfWithElse) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* else_body = Block(Return());
@@ -88,8 +88,8 @@
}
TEST_F(HlslGeneratorImplTest_If, Emit_IfWithMultiple) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
- Global("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* else_cond = Expr("else_cond");
diff --git a/src/tint/writer/hlsl/generator_impl_import_test.cc b/src/tint/writer/hlsl/generator_impl_import_test.cc
index f7d544e..d6fdeac 100644
--- a/src/tint/writer/hlsl/generator_impl_import_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_import_test.cc
@@ -259,7 +259,7 @@
testing::Values(HlslImportData{"clamp", "clamp"}));
TEST_F(HlslGeneratorImplTest_Import, HlslImportData_Determinant) {
- Global("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("determinant", "var");
WrapInFunction(expr);
diff --git a/src/tint/writer/hlsl/generator_impl_loop_test.cc b/src/tint/writer/hlsl/generator_impl_loop_test.cc
index 29d1822..9f288f6 100644
--- a/src/tint/writer/hlsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_loop_test.cc
@@ -66,8 +66,8 @@
TEST_F(HlslGeneratorImplTest_Loop, Emit_LoopNestedWithContinuing) {
Func("a_statement", {}, ty.void_(), {});
- Global("lhs", ty.f32(), ast::StorageClass::kPrivate);
- Global("rhs", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("lhs", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
auto* body = Block(create<ast::DiscardStatement>());
auto* continuing = Block(CallStmt(Call("a_statement")));
@@ -112,7 +112,7 @@
// }
// }
- Global("rhs", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4_f))), //
Decl(Var("other", ty.f32())), //
diff --git a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
index ffa64fd..8149b7f 100644
--- a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -91,11 +91,11 @@
auto* s = b.Structure("Data", members);
- b.Global("data", b.ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- b.create<ast::BindingAttribute>(0),
- b.create<ast::GroupAttribute>(1),
- });
+ b.GlobalVar("data", b.ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ b.create<ast::BindingAttribute>(0u),
+ b.create<ast::GroupAttribute>(1u),
+ });
}
void SetupFunction(ast::StatementList statements) {
@@ -115,7 +115,7 @@
TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
auto* s = Structure("Data", {Member("mem", ty.f32())});
- Global("str", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("str", "mem");
WrapInFunction(Var("expr", ty.f32(), ast::StorageClass::kNone, expr));
diff --git a/src/tint/writer/hlsl/generator_impl_module_constant_test.cc b/src/tint/writer/hlsl/generator_impl_module_constant_test.cc
index 19be5e6..3a988a0 100644
--- a/src/tint/writer/hlsl/generator_impl_module_constant_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_module_constant_test.cc
@@ -22,17 +22,180 @@
using HlslGeneratorImplTest_ModuleConstant = TestHelper;
-TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
- auto* var = Let("pos", ty.array<f32, 3>(), array<f32, 3>(1_f, 2_f, 3_f));
- WrapInFunction(Decl(var));
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AInt) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
- ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
- EXPECT_EQ(gen.result(), "static const float pos[3] = {1.0f, 2.0f, 3.0f};\n");
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const int l = 1;
+}
+)");
}
-TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant) {
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AFloat) {
+ auto* var = GlobalConst("G", nullptr, Expr(1._a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float l = 1.0f;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_i32) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_i));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const int l = 1;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_u32) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_u));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const uint l = 1u;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_f32) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float l = 1.0f;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AInt) {
+ auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const int3 l = int3(1, 2, 3);
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AFloat) {
+ auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float3 l = float3(1.0f, 2.0f, 3.0f);
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_f32) {
+ auto* var = GlobalConst("G", nullptr, vec3<f32>(1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float3 l = float3(1.0f, 2.0f, 3.0f);
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_AFloat) {
+ auto* var = GlobalConst("G", nullptr,
+ Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float2x3 l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_f32) {
+ auto* var = GlobalConst("G", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float2x3 l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_f32) {
+ auto* var = GlobalConst("G", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float l[3] = {1.0f, 2.0f, 3.0f};
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_vec2_bool) {
+ auto* var = GlobalConst("G", nullptr,
+ Construct(ty.array(ty.vec2<bool>(), 3_u), //
+ vec2<bool>(true, false), //
+ vec2<bool>(false, true), //
+ vec2<bool>(true, true)));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const bool2 l[3] = {bool2(true, false), bool2(false, true), (true).xx};
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_Override) {
auto* var = Override("pos", ty.f32(), Expr(3_f),
ast::AttributeList{
Id(23),
@@ -48,7 +211,7 @@
)");
}
-TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoConstructor) {
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_Override_NoConstructor) {
auto* var = Override("pos", ty.f32(), nullptr,
ast::AttributeList{
Id(23),
@@ -64,7 +227,7 @@
)");
}
-TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoId) {
+TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_Override_NoId) {
auto* a = Override("a", ty.f32(), Expr(3_f),
ast::AttributeList{
Id(0),
diff --git a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
index e7b81e4..3bb1cec 100644
--- a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
@@ -26,11 +26,11 @@
TEST_F(HlslSanitizerTest, Call_ArrayLength) {
auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
{
@@ -64,11 +64,11 @@
Member(0, "z", ty.f32()),
Member(4, "a", ty.array<f32>(4)),
});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
{
@@ -100,11 +100,11 @@
TEST_F(HlslSanitizerTest, Call_ArrayLength_ViaLets) {
auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
auto* p = Let("p", nullptr, AddressOf("b"));
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
@@ -140,16 +140,16 @@
TEST_F(HlslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniform) {
auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
- Global("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(2),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
+ GlobalVar("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(2u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
{
@@ -188,12 +188,11 @@
TEST_F(HlslSanitizerTest, PromoteArrayInitializerToConstVar) {
auto* array_init = array<i32, 4>(1_i, 2_i, 3_i, 4_i);
- auto* array_index = IndexAccessor(array_init, 3_i);
- auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
Func("main", {}, ty.void_(),
{
- Decl(pos),
+ Decl(Var("idx", nullptr, Expr(3_i))),
+ Decl(Var("pos", ty.i32(), IndexAccessor(array_init, "idx"))),
},
{
Stage(ast::PipelineStage::kFragment),
@@ -205,8 +204,9 @@
auto got = gen.result();
auto* expect = R"(void main() {
+ int idx = 3;
const int tint_symbol[4] = {1, 2, 3, 4};
- int pos = tint_symbol[3];
+ int pos = tint_symbol[idx];
return;
}
)";
diff --git a/src/tint/writer/hlsl/generator_impl_switch_test.cc b/src/tint/writer/hlsl/generator_impl_switch_test.cc
index 3ef1a7b..7d89672 100644
--- a/src/tint/writer/hlsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_switch_test.cc
@@ -22,7 +22,7 @@
using HlslGeneratorImplTest_Switch = TestHelper;
TEST_F(HlslGeneratorImplTest_Switch, Emit_Switch) {
- Global("cond", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.i32(), ast::StorageClass::kPrivate);
auto* s = Switch( //
Expr("cond"), //
Case(Expr(5_i), Block(Break())), //
@@ -46,8 +46,8 @@
}
TEST_F(HlslGeneratorImplTest_Switch, Emit_Switch_OnlyDefaultCase) {
- Global("cond", ty.i32(), ast::StorageClass::kPrivate);
- Global("a", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
auto* s = Switch( //
Expr("cond"), //
DefaultCase(Block(Assign(Expr("a"), Expr(42_i)))));
diff --git a/src/tint/writer/hlsl/generator_impl_type_test.cc b/src/tint/writer/hlsl/generator_impl_type_test.cc
index b99f06e..614d8f1 100644
--- a/src/tint/writer/hlsl/generator_impl_type_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_type_test.cc
@@ -33,7 +33,7 @@
TEST_F(HlslGeneratorImplTest_Type, EmitType_Array) {
auto* arr = ty.array<bool, 4>();
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -46,7 +46,7 @@
TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArray) {
auto* arr = ty.array(ty.array<bool, 4>(), 5_u);
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -59,7 +59,7 @@
TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArrayOfArray) {
auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5_u), 6_u);
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -72,7 +72,7 @@
TEST_F(HlslGeneratorImplTest_Type, EmitType_Array_WithoutName) {
auto* arr = ty.array<bool, 4>();
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -134,7 +134,7 @@
Member("a", ty.i32()),
Member("b", ty.f32()),
});
- Global("g", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -153,11 +153,11 @@
Member("a", ty.i32()),
Member("b", ty.f32()),
});
- Global("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -170,7 +170,7 @@
Member("a", ty.i32()),
Member("b", ty.f32()),
});
- Global("g", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -186,7 +186,7 @@
Member("double", ty.i32()),
Member("float", ty.f32()),
});
- Global("g", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
GeneratorImpl& gen = SanitizeAndBuild();
@@ -203,7 +203,7 @@
Member("a", ty.i32(), {MemberOffset(0)}),
Member("b", ty.f32(), {MemberOffset(8)}),
});
- Global("g", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -287,11 +287,11 @@
auto* t = ty.depth_texture(params.dim);
- Global("tex", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("tex", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
{Stage(ast::PipelineStage::kFragment)});
@@ -317,11 +317,11 @@
TEST_F(HlslDepthMultisampledTexturesTest, Emit) {
auto* t = ty.depth_multisampled_texture(ast::TextureDimension::k2d);
- Global("tex", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("tex", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
{Stage(ast::PipelineStage::kFragment)});
@@ -360,11 +360,11 @@
}
auto* t = ty.sampled_texture(params.dim, datatype);
- Global("tex", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("tex", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
{Stage(ast::PipelineStage::kFragment)});
@@ -495,7 +495,7 @@
auto* t = ty.storage_texture(params.dim, params.imgfmt, ast::Access::kWrite);
- Global("tex", t, ast::AttributeList{GroupAndBinding(2, 1)});
+ GlobalVar("tex", t, ast::AttributeList{GroupAndBinding(2, 1)});
Func("main", {}, ty.void_(), {CallStmt(Call("textureDimensions", "tex"))},
{Stage(ast::PipelineStage::kFragment)});
diff --git a/src/tint/writer/hlsl/generator_impl_unary_op_test.cc b/src/tint/writer/hlsl/generator_impl_unary_op_test.cc
index c9abf1f..74320ea 100644
--- a/src/tint/writer/hlsl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
using HlslUnaryOpTest = TestHelper;
TEST_F(HlslUnaryOpTest, AddressOf) {
- Global("expr", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.f32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
WrapInFunction(op);
@@ -32,7 +32,7 @@
}
TEST_F(HlslUnaryOpTest, Complement) {
- Global("expr", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.u32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
WrapInFunction(op);
@@ -44,7 +44,7 @@
}
TEST_F(HlslUnaryOpTest, Indirection) {
- Global("G", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("G", ty.f32(), ast::StorageClass::kPrivate);
auto* p =
Let("expr", nullptr, create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
@@ -58,7 +58,7 @@
}
TEST_F(HlslUnaryOpTest, Not) {
- Global("expr", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.bool_(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
WrapInFunction(op);
@@ -70,7 +70,7 @@
}
TEST_F(HlslUnaryOpTest, Negation) {
- Global("expr", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.i32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
WrapInFunction(op);
diff --git a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
index 5ed85f3..1e111cd 100644
--- a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
@@ -16,6 +16,8 @@
#include "src/tint/ast/variable_decl_statement.h"
#include "src/tint/writer/hlsl/test_helper.h"
+using namespace tint::number_suffixes; // NOLINT
+
namespace tint::writer::hlsl {
namespace {
@@ -36,7 +38,7 @@
EXPECT_EQ(gen.result(), " float a = 0.0f;\n");
}
-TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Let) {
auto* var = Let("a", ty.f32(), Construct(ty.f32()));
auto* stmt = Decl(var);
WrapInFunction(stmt);
@@ -49,6 +51,192 @@
EXPECT_EQ(gen.result(), " const float a = 0.0f;\n");
}
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
+ auto* var = Const("a", ty.f32(), Construct(ty.f32()));
+ auto* stmt = Decl(var);
+ WrapInFunction(stmt);
+
+ GeneratorImpl& gen = Build();
+
+ gen.increment_indent();
+
+ ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
+ EXPECT_EQ(gen.result(), ""); // Not a mistake - 'const' is inlined
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AInt) {
+ auto* C = Const("C", nullptr, Expr(1_a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const int l = 1;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AFloat) {
+ auto* C = Const("C", nullptr, Expr(1._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float l = 1.0f;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_i32) {
+ auto* C = Const("C", nullptr, Expr(1_i));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const int l = 1;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_u32) {
+ auto* C = Const("C", nullptr, Expr(1_u));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const uint l = 1u;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_f32) {
+ auto* C = Const("C", nullptr, Expr(1_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float l = 1.0f;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AInt) {
+ auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const int3 l = int3(1, 2, 3);
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AFloat) {
+ auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float3 l = float3(1.0f, 2.0f, 3.0f);
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_f32) {
+ auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float3 l = float3(1.0f, 2.0f, 3.0f);
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
+ auto* C =
+ Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float2x3 l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_f32) {
+ auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float2x3 l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_f32) {
+ auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const float l[3] = {1.0f, 2.0f, 3.0f};
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
+ auto* C = Const("C", nullptr,
+ Construct(ty.array(ty.vec2<bool>(), 3_u), //
+ vec2<bool>(true, false), //
+ vec2<bool>(false, true), //
+ vec2<bool>(true, true)));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(void f() {
+ const bool2 l[3] = {bool2(true, false), bool2(false, true), (true).xx};
+}
+)");
+}
+
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Array) {
auto* var = Var("a", ty.array<f32, 5>());
@@ -63,7 +251,7 @@
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
- Global("a", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
WrapInFunction(Expr("a"));
@@ -75,19 +263,6 @@
EXPECT_THAT(gen.result(), HasSubstr(" static float a = 0.0f;\n"));
}
-TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initializer_Private) {
- Global("initializer", ty.f32(), ast::StorageClass::kPrivate);
- Global("a", ty.f32(), ast::StorageClass::kPrivate, Expr("initializer"));
-
- WrapInFunction(Expr("a"));
-
- GeneratorImpl& gen = Build();
-
- ASSERT_TRUE(gen.Generate()) << gen.error();
- EXPECT_THAT(gen.result(), HasSubstr(R"(float a = initializer;
-)"));
-}
-
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initializer_ZeroVec) {
auto* var = Var("a", ty.vec3<f32>(), ast::StorageClass::kNone, vec3<f32>());
diff --git a/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc b/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
index 826a545..5de44b1 100644
--- a/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
@@ -27,7 +27,7 @@
using HlslGeneratorImplTest_WorkgroupVar = TestHelper;
TEST_F(HlslGeneratorImplTest_WorkgroupVar, Basic) {
- Global("wg", ty.f32(), ast::StorageClass::kWorkgroup);
+ GlobalVar("wg", ty.f32(), ast::StorageClass::kWorkgroup);
Func("main", {}, ty.void_(), {Assign("wg", 1.2_f)},
{
@@ -43,7 +43,7 @@
TEST_F(HlslGeneratorImplTest_WorkgroupVar, Aliased) {
auto* alias = Alias("F32", ty.f32());
- Global("wg", ty.Of(alias), ast::StorageClass::kWorkgroup);
+ GlobalVar("wg", ty.Of(alias), ast::StorageClass::kWorkgroup);
Func("main", {}, ty.void_(), {Assign("wg", 1.2_f)},
{
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc
index 1181c02..43324bb 100644
--- a/src/tint/writer/msl/generator_impl.cc
+++ b/src/tint/writer/msl/generator_impl.cc
@@ -64,14 +64,13 @@
#include "src/tint/transform/expand_compound_assignment.h"
#include "src/tint/transform/manager.h"
#include "src/tint/transform/module_scope_var_to_entry_point_param.h"
-#include "src/tint/transform/promote_initializers_to_const_var.h"
+#include "src/tint/transform/promote_initializers_to_let.h"
#include "src/tint/transform/promote_side_effects_to_decl.h"
#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/unshadow.h"
#include "src/tint/transform/unwind_discard_functions.h"
#include "src/tint/transform/vectorize_scalar_matrix_constructors.h"
-#include "src/tint/transform/wrap_arrays_in_structs.h"
#include "src/tint/transform/zero_init_workgroup_memory.h"
#include "src/tint/utils/defer.h"
#include "src/tint/utils/map.h"
@@ -152,6 +151,8 @@
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
+ polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
+ polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.extract_bits = transform::BuiltinPolyfill::Level::kClampParameters;
polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true;
@@ -205,10 +206,9 @@
manager.Add<transform::ExpandCompoundAssignment>();
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::UnwindDiscardFunctions>();
- manager.Add<transform::PromoteInitializersToConstVar>();
+ manager.Add<transform::PromoteInitializersToLet>();
manager.Add<transform::VectorizeScalarMatrixConstructors>();
- manager.Add<transform::WrapArraysInStructs>();
manager.Add<transform::RemovePhonies>();
manager.Add<transform::SimplifyPointers>();
// ArrayLengthFromUniform must come after SimplifyPointers, as
@@ -253,9 +253,8 @@
[&](const ast::Alias*) {
return true; // folded away by the writer
},
- [&](const ast::Let* let) {
- TINT_DEFER(line());
- return EmitProgramConstVariable(let);
+ [&](const ast::Const*) {
+ return true; // Constants are embedded at their use
},
[&](const ast::Override* override) {
TINT_DEFER(line());
@@ -731,16 +730,36 @@
const sem::TypeConstructor* ctor) {
auto* type = ctor->ReturnType();
- if (type->IsAnyOf<sem::Array, sem::Struct>()) {
- out << "{";
- } else {
- if (!EmitType(out, type, "")) {
- return false;
- }
- out << "(";
+ const char* terminator = ")";
+ TINT_DEFER(out << terminator);
+
+ bool ok = Switch(
+ type,
+ [&](const sem::Array*) {
+ if (!EmitType(out, type, "")) {
+ return false;
+ }
+ out << "{";
+ terminator = "}";
+ return true;
+ },
+ [&](const sem::Struct*) {
+ out << "{";
+ terminator = "}";
+ return true;
+ },
+ [&](Default) {
+ if (!EmitType(out, type, "")) {
+ return false;
+ }
+ out << "(";
+ return true;
+ });
+ if (!ok) {
+ return false;
}
- int i = 0;
+ size_t i = 0;
for (auto* arg : call->Arguments()) {
if (i > 0) {
out << ", ";
@@ -760,11 +779,6 @@
i++;
}
- if (type->IsAnyOf<sem::Array, sem::Struct>()) {
- out << "}";
- } else {
- out << ")";
- }
return true;
}
@@ -906,7 +920,7 @@
// Returns the argument with the given usage
auto arg = [&](Usage usage) {
int idx = signature.IndexOf(usage);
- return (idx >= 0) ? arguments[idx] : nullptr;
+ return (idx >= 0) ? arguments[static_cast<size_t>(idx)] : nullptr;
};
auto* texture = arg(Usage::kTexture)->Declaration();
@@ -1187,7 +1201,7 @@
break; // Other texture dimensions don't have an offset
}
}
- auto c = component->ConstantValue().Element<AInt>(0);
+ auto c = component->ConstantValue()->As<AInt>();
switch (c.value) {
case 0:
out << "component::x";
@@ -1335,9 +1349,12 @@
std::string out = "";
switch (builtin->Type()) {
case sem::BuiltinType::kAcos:
+ case sem::BuiltinType::kAcosh:
case sem::BuiltinType::kAll:
case sem::BuiltinType::kAny:
case sem::BuiltinType::kAsin:
+ case sem::BuiltinType::kAsinh:
+ case sem::BuiltinType::kAtanh:
case sem::BuiltinType::kAtan:
case sem::BuiltinType::kAtan2:
case sem::BuiltinType::kCeil:
@@ -1561,10 +1578,9 @@
ScopedParen sp(out);
return EmitZeroValue(out, mat->type());
},
- [&](const sem::Array* arr) {
- out << "{";
- TINT_DEFER(out << "}");
- return EmitZeroValue(out, arr->ElemType());
+ [&](const sem::Array*) {
+ out << "{}";
+ return true;
},
[&](const sem::Struct*) {
out << "{}";
@@ -1578,88 +1594,94 @@
});
}
-bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant& constant) {
- auto emit_bool = [&](size_t element_idx) {
- out << (constant.Element<AInt>(element_idx) ? "true" : "false");
- return true;
- };
- auto emit_f32 = [&](size_t element_idx) {
- PrintF32(out, static_cast<float>(constant.Element<AFloat>(element_idx)));
- return true;
- };
- auto emit_i32 = [&](size_t element_idx) {
- PrintI32(out, static_cast<int32_t>(constant.Element<AInt>(element_idx).value));
- return true;
- };
- auto emit_u32 = [&](size_t element_idx) {
- out << constant.Element<AInt>(element_idx).value << "u";
- return true;
- };
- auto emit_vector = [&](const sem::Vector* vec_ty, size_t start, size_t end) {
- if (!EmitType(out, vec_ty, "")) {
- return false;
- }
-
- ScopedParen sp(out);
-
- auto emit_els = [&](auto emit_el) {
- if (constant.AllEqual(start, end)) {
- return emit_el(start);
+bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant* constant) {
+ return Switch(
+ constant->Type(), //
+ [&](const sem::Bool*) {
+ out << (constant->As<AInt>() ? "true" : "false");
+ return true;
+ },
+ [&](const sem::F32*) {
+ PrintF32(out, constant->As<float>());
+ return true;
+ },
+ [&](const sem::I32*) {
+ PrintI32(out, constant->As<int32_t>());
+ return true;
+ },
+ [&](const sem::U32*) {
+ out << constant->As<AInt>() << "u";
+ return true;
+ },
+ [&](const sem::Vector* v) {
+ if (!EmitType(out, v, "")) {
+ return false;
}
- for (size_t i = start; i < end; i++) {
- if (i > start) {
+
+ ScopedParen sp(out);
+
+ if (constant->AllEqual()) {
+ if (!EmitConstant(out, constant->Index(0))) {
+ return false;
+ }
+ return true;
+ }
+
+ for (size_t i = 0; i < v->Width(); i++) {
+ if (i > 0) {
out << ", ";
}
- if (!emit_el(i)) {
+ if (!EmitConstant(out, constant->Index(i))) {
return false;
}
}
return true;
- };
- return Switch(
- vec_ty->type(), //
- [&](const sem::Bool*) { return emit_els(emit_bool); }, //
- [&](const sem::F32*) { return emit_els(emit_f32); }, //
- [&](const sem::I32*) { return emit_els(emit_i32); }, //
- [&](const sem::U32*) { return emit_els(emit_u32); }, //
- [&](Default) {
- diagnostics_.add_error(diag::System::Writer,
- "unhandled constant vector element type: " +
- builder_.FriendlyName(vec_ty->type()));
- return false;
- });
- };
- auto emit_matrix = [&](const sem::Matrix* m) {
- if (!EmitType(out, constant.Type(), "")) {
- return false;
- }
-
- ScopedParen sp(out);
-
- for (size_t column_idx = 0; column_idx < m->columns(); column_idx++) {
- if (column_idx > 0) {
- out << ", ";
- }
- size_t start = m->rows() * column_idx;
- size_t end = m->rows() * (column_idx + 1);
- if (!emit_vector(m->ColumnType(), start, end)) {
+ },
+ [&](const sem::Matrix* m) {
+ if (!EmitType(out, m, "")) {
return false;
}
- }
- return true;
- };
- return Switch(
- constant.Type(), //
- [&](const sem::Bool*) { return emit_bool(0); }, //
- [&](const sem::F32*) { return emit_f32(0); }, //
- [&](const sem::I32*) { return emit_i32(0); }, //
- [&](const sem::U32*) { return emit_u32(0); }, //
- [&](const sem::Vector* v) { return emit_vector(v, 0, constant.ElementCount()); }, //
- [&](const sem::Matrix* m) { return emit_matrix(m); }, //
+
+ ScopedParen sp(out);
+
+ for (size_t i = 0; i < m->columns(); i++) {
+ if (i > 0) {
+ out << ", ";
+ }
+ if (!EmitConstant(out, constant->Index(i))) {
+ return false;
+ }
+ }
+ return true;
+ },
+ [&](const sem::Array* a) {
+ if (!EmitType(out, a, "")) {
+ return false;
+ }
+
+ if (constant->AllZero()) {
+ out << "{}";
+ return true;
+ }
+
+ out << "{";
+ TINT_DEFER(out << "}");
+
+ for (size_t i = 0; i < a->Count(); i++) {
+ if (i > 0) {
+ out << ", ";
+ }
+ if (!EmitConstant(out, constant->Index(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ },
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,
- "unhandled constant type: " + builder_.FriendlyName(constant.Type()));
+ "unhandled constant type: " + builder_.FriendlyName(constant->Type()));
return false;
});
}
@@ -1698,8 +1720,14 @@
bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) {
if (auto* sem = builder_.Sem().Get(expr)) {
- if (auto constant = sem->ConstantValue()) {
- return EmitConstant(out, constant);
+ if (auto* user = sem->As<sem::VariableUser>();
+ !user || !user->Variable()->Declaration()->Is<ast::Let>()) {
+ // Disable constant inlining if the constant expression is from a 'let' declaration.
+ // TODO(crbug.com/tint/1580): Once 'const' is implemented, 'let' will no longer resolve
+ // to a shader-creation time constant value, and this can be removed.
+ if (auto constant = sem->ConstantValue()) {
+ return EmitConstant(out, constant);
+ }
}
}
return Switch(
@@ -1775,8 +1803,8 @@
if (!EmitType(out, type, param_name)) {
return false;
}
- // Parameter name is output as part of the type for arrays and pointers.
- if (!type->Is<sem::Array>() && !type->Is<sem::Pointer>()) {
+ // Parameter name is output as part of the type for pointers.
+ if (!type->Is<sem::Pointer>()) {
out << " " << program_->Symbols().NameFor(v->symbol);
}
}
@@ -1899,8 +1927,8 @@
if (!EmitType(out, type, param_name)) {
return false;
}
- // Parameter name is output as part of the type for arrays and pointers.
- if (!type->Is<sem::Array>() && !type->Is<sem::Pointer>()) {
+ // Parameter name is output as part of the type for pointers.
+ if (!type->Is<sem::Pointer>()) {
out << " " << param_name;
}
@@ -2341,6 +2369,9 @@
v->variable, //
[&](const ast::Var* var) { return EmitVar(var); },
[&](const ast::Let* let) { return EmitLet(let); },
+ [&](const ast::Const*) {
+ return true; // Constants are embedded at their use
+ },
[&](Default) { //
TINT_ICE(Writer, diagnostics_)
<< "unknown statement type: " << stmt->TypeInfo().name;
@@ -2415,29 +2446,12 @@
<< "unhandled atomic type " << atomic->Type()->FriendlyName(builder_.Symbols());
return false;
},
- [&](const sem::Array* ary) {
- const sem::Type* base_type = ary;
- std::vector<uint32_t> sizes;
- while (auto* arr = base_type->As<sem::Array>()) {
- if (arr->IsRuntimeSized()) {
- sizes.push_back(1);
- } else {
- sizes.push_back(arr->Count());
- }
- base_type = arr->ElemType();
- }
- if (!EmitType(out, base_type, "")) {
+ [&](const sem::Array* arr) {
+ out << ArrayType() << "<";
+ if (!EmitType(out, arr->ElemType(), "")) {
return false;
}
- if (!name.empty()) {
- out << " " << name;
- if (name_printed) {
- *name_printed = true;
- }
- }
- for (uint32_t size : sizes) {
- out << "[" << size << "]";
- }
+ out << ", " << (arr->IsRuntimeSized() ? 1u : arr->Count()) << ">";
return true;
},
[&](const sem::Bool*) {
@@ -2472,22 +2486,12 @@
return false;
}
out << " ";
- if (ptr->StoreType()->Is<sem::Array>()) {
- std::string inner = "(*" + name + ")";
- if (!EmitType(out, ptr->StoreType(), inner)) {
- return false;
- }
- if (name_printed) {
- *name_printed = true;
- }
- } else {
- if (!EmitType(out, ptr->StoreType(), "")) {
- return false;
- }
- out << "* " << name;
- if (name_printed) {
- *name_printed = true;
- }
+ if (!EmitType(out, ptr->StoreType(), "")) {
+ return false;
+ }
+ out << "* " << name;
+ if (name_printed) {
+ *name_printed = true;
}
return true;
},
@@ -2703,7 +2707,7 @@
auto out = line(b);
add_byte_offset_comment(out, msl_offset);
- out << "int8_t " << name << "[" << size << "];";
+ out << ArrayType() << "<int8_t, " << size << "> " << name << ";";
};
b->IncrementIndent();
@@ -2741,11 +2745,7 @@
auto* ty = mem->Type();
- // Array member name will be output with the type
- if (!ty->Is<sem::Array>()) {
- out << " " << mem_name;
- }
-
+ out << " " << mem_name;
// Emit attributes
if (auto* decl = mem->Declaration()) {
for (auto* attr : decl->attributes) {
@@ -2948,8 +2948,8 @@
if (!EmitType(out, type, name)) {
return false;
}
- // Variable name is output as part of the type for arrays and pointers.
- if (!type->Is<sem::Array>() && !type->Is<sem::Pointer>()) {
+ // Variable name is output as part of the type for pointers.
+ if (!type->Is<sem::Pointer>()) {
out << " " << name;
}
@@ -2998,8 +2998,8 @@
return false;
}
- // Variable name is output as part of the type for arrays and pointers.
- if (!type->Is<sem::Array>() && !type->Is<sem::Pointer>()) {
+ // Variable name is output as part of the type for pointers.
+ if (!type->Is<sem::Pointer>()) {
out << " " << name;
}
@@ -3012,30 +3012,6 @@
return true;
}
-bool GeneratorImpl::EmitProgramConstVariable(const ast::Let* let) {
- auto* global = program_->Sem().Get<sem::GlobalVariable>(let);
- auto* type = global->Type();
-
- auto out = line();
- out << "constant ";
- if (!EmitType(out, type, program_->Symbols().NameFor(let->symbol))) {
- return false;
- }
- if (!type->Is<sem::Array>()) {
- out << " " << program_->Symbols().NameFor(let->symbol);
- }
-
- if (let->constructor != nullptr) {
- out << " = ";
- if (!EmitExpression(out, let->constructor)) {
- return false;
- }
- }
- out << ";";
-
- return true;
-}
-
bool GeneratorImpl::EmitOverride(const ast::Override* override) {
auto* global = program_->Sem().Get<sem::GlobalVariable>(override);
auto* type = global->Type();
@@ -3045,9 +3021,7 @@
if (!EmitType(out, type, program_->Symbols().NameFor(override->symbol))) {
return false;
}
- if (!type->Is<sem::Array>()) {
- out << " " << program_->Symbols().NameFor(override->symbol);
- }
+ out << " " << program_->Symbols().NameFor(override->symbol);
out << " [[function_constant(" << global->ConstantId() << ")]];";
@@ -3120,8 +3094,8 @@
[&](const sem::Array* arr) {
if (!arr->IsStrideImplicit()) {
- TINT_ICE(Writer, diagnostics_) << "arrays with explicit strides not "
- "exist past the SPIR-V reader";
+ TINT_ICE(Writer, diagnostics_)
+ << "arrays with explicit strides should not exist past the SPIR-V reader";
return SizeAndAlign{};
}
auto num_els = std::max<uint32_t>(arr->Count(), 1);
@@ -3208,4 +3182,25 @@
return true;
}
+const std::string& GeneratorImpl::ArrayType() {
+ if (array_template_name_.empty()) {
+ array_template_name_ = UniqueIdentifier("tint_array");
+ auto* buf = &helpers_;
+ line(buf) << "template<typename T, size_t N>";
+ line(buf) << "struct " << array_template_name_ << " {";
+ line(buf) << " const constant T& operator[](size_t i) const constant"
+ << " { return elements[i]; }";
+ for (auto* space : {"device", "thread", "threadgroup"}) {
+ line(buf) << " " << space << " T& operator[](size_t i) " << space
+ << " { return elements[i]; }";
+ line(buf) << " const " << space << " T& operator[](size_t i) const " << space
+ << " { return elements[i]; }";
+ }
+ line(buf) << " T elements[N];";
+ line(buf) << "};";
+ line(buf);
+ }
+ return array_template_name_;
+}
+
} // namespace tint::writer::msl
diff --git a/src/tint/writer/msl/generator_impl.h b/src/tint/writer/msl/generator_impl.h
index 59af5c3..f27d258 100644
--- a/src/tint/writer/msl/generator_impl.h
+++ b/src/tint/writer/msl/generator_impl.h
@@ -256,7 +256,7 @@
/// @param out the output stream
/// @param constant the constant value to emit
/// @returns true if the constant value was successfully emitted
- bool EmitConstant(std::ostream& out, const sem::Constant& constant);
+ bool EmitConstant(std::ostream& out, const sem::Constant* constant);
/// Handles a literal
/// @param out the output of the expression stream
/// @param lit the literal to emit
@@ -356,10 +356,6 @@
/// @param let the variable to generate
/// @returns true if the variable was emitted
bool EmitLet(const ast::Let* let);
- /// Handles generating a module-scope 'let' declaration
- /// @param let the 'let' to emit
- /// @returns true if the variable was emitted
- bool EmitProgramConstVariable(const ast::Let* let);
/// Handles generating a module-scope 'override' declaration
/// @param override the 'override' to emit
/// @returns true if the variable was emitted
@@ -413,6 +409,10 @@
const sem::Builtin* builtin,
F&& build);
+ /// @returns the name of the templated tint_array helper type, generating it if this is the
+ /// first call.
+ const std::string& ArrayType();
+
TextBuffer helpers_; // Helper functions emitted at the top of the output
/// @returns the MSL packed type size and alignment in bytes for the given
@@ -427,13 +427,17 @@
utils::UnorderedKeyWrapper<std::tuple<ast::StorageClass, const sem::Struct*>>;
std::unordered_map<ACEWKeyType, std::string> atomicCompareExchangeWeak_;
- /// Unique name of the 'TINT_INVARIANT' preprocessor define. Non-empty only if
- /// an invariant attribute has been generated.
+ /// Unique name of the 'TINT_INVARIANT' preprocessor define.
+ /// Non-empty only if an invariant attribute has been generated.
std::string invariant_define_name_;
/// True if matrix-packed_vector operator overloads have been generated.
bool matrix_packed_vector_overloads_ = false;
+ /// Unique name of the tint_array<T, N> template.
+ /// Non-empty only if the template has been generated.
+ std::string array_template_name_;
+
/// A map from entry point name to a list of dynamic workgroup allocations.
/// Each entry in the vector is the size of the workgroup allocation that
/// should be created for that index.
diff --git a/src/tint/writer/msl/generator_impl_array_accessor_test.cc b/src/tint/writer/msl/generator_impl_array_accessor_test.cc
index 7475b67..bfa76dc 100644
--- a/src/tint/writer/msl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/msl/generator_impl_array_accessor_test.cc
@@ -34,7 +34,7 @@
}
TEST_F(MslGeneratorImplTest, IndexAccessor_OfDref) {
- Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
+ GlobalVar("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
auto* p = Let("p", nullptr, AddressOf("ary"));
auto* expr = IndexAccessor(Deref("p"), 5_i);
diff --git a/src/tint/writer/msl/generator_impl_builtin_test.cc b/src/tint/writer/msl/generator_impl_builtin_test.cc
index bfe5548..9f00be7 100644
--- a/src/tint/writer/msl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/msl/generator_impl_builtin_test.cc
@@ -171,15 +171,15 @@
TEST_P(MslBuiltinTest, Emit) {
auto param = GetParam();
- Global("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
- Global("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
- Global("f4", ty.vec4<f32>(), ast::StorageClass::kPrivate);
- Global("u1", ty.u32(), ast::StorageClass::kPrivate);
- Global("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
- Global("i2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
- Global("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
- Global("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
- Global("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("f4", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("u1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
+ GlobalVar("i2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
+ GlobalVar("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
auto* call = GenerateCall(param.builtin, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled builtin";
@@ -273,8 +273,8 @@
BuiltinData{BuiltinType::kUnpack2x16unorm, ParamType::kU32, "unpack_unorm2x16_to_float"}));
TEST_F(MslGeneratorImplTest, Builtin_Call) {
- Global("param1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
- Global("param2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
auto* call = Call("dot", "param1", "param2");
WrapInFunction(CallStmt(call));
@@ -410,7 +410,7 @@
TEST_F(MslGeneratorImplTest, Pack2x16Float) {
auto* call = Call("pack2x16float", "p1");
- Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -422,7 +422,7 @@
TEST_F(MslGeneratorImplTest, Unpack2x16Float) {
auto* call = Call("unpack2x16float", "p1");
- Global("p1", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@@ -433,7 +433,7 @@
}
TEST_F(MslGeneratorImplTest, DotI32) {
- Global("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+ GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(Call("dot", "v", "v")));
GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/msl/generator_impl_call_test.cc b/src/tint/writer/msl/generator_impl_call_test.cc
index 93c9b83..c7f3a02 100644
--- a/src/tint/writer/msl/generator_impl_call_test.cc
+++ b/src/tint/writer/msl/generator_impl_call_test.cc
@@ -42,8 +42,8 @@
Param(Sym(), ty.f32()),
},
ty.f32(), {Return(1.23_f)});
- Global("param1", ty.f32(), ast::StorageClass::kPrivate);
- Global("param2", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
auto* call = Call("my_func", "param1", "param2");
WrapInFunction(call);
@@ -62,8 +62,8 @@
Param(Sym(), ty.f32()),
},
ty.void_(), ast::StatementList{}, ast::AttributeList{});
- Global("param1", ty.f32(), ast::StorageClass::kPrivate);
- Global("param2", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
auto* call = Call("my_func", "param1", "param2");
auto* stmt = CallStmt(call);
diff --git a/src/tint/writer/msl/generator_impl_function_test.cc b/src/tint/writer/msl/generator_impl_function_test.cc
index f7d2779..e520d7a 100644
--- a/src/tint/writer/msl/generator_impl_function_test.cc
+++ b/src/tint/writer/msl/generator_impl_function_test.cc
@@ -335,11 +335,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
@@ -377,11 +377,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
@@ -415,11 +415,11 @@
TEST_F(MslGeneratorImplTest, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
auto* ubo_ty = Structure("UBO", {Member("coord", ty.vec4<f32>())});
- auto* ubo = Global("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* ubo = GlobalVar("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
Func("sub_func",
{
@@ -469,11 +469,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
Func("sub_func",
{
@@ -524,11 +524,11 @@
Member("b", ty.f32()),
});
- Global("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
Func("sub_func",
{
@@ -591,11 +591,20 @@
EXPECT_EQ(gen.result(), R"( #include <metal_stdlib>
using namespace metal;
- struct tint_array_wrapper {
- float arr[5];
- };
- void my_func(tint_array_wrapper a) {
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+ void my_func(tint_array<float, 5> a) {
return;
}
@@ -616,12 +625,21 @@
EXPECT_EQ(gen.result(), R"( #include <metal_stdlib>
using namespace metal;
- struct tint_array_wrapper {
- float arr[5];
- };
- tint_array_wrapper my_func() {
- tint_array_wrapper const tint_symbol = {.arr={}};
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+ tint_array<float, 5> my_func() {
+ tint_array<float, 5> const tint_symbol = tint_array<float, 5>{};
return tint_symbol;
}
@@ -647,11 +665,11 @@
auto* s = Structure("Data", {Member("d", ty.f32())});
- Global("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
diff --git a/src/tint/writer/msl/generator_impl_import_test.cc b/src/tint/writer/msl/generator_impl_import_test.cc
index de9353e..7b79569 100644
--- a/src/tint/writer/msl/generator_impl_import_test.cc
+++ b/src/tint/writer/msl/generator_impl_import_test.cc
@@ -234,7 +234,7 @@
MslImportData{"clamp", "clamp"}));
TEST_F(MslGeneratorImplTest, MslImportData_Determinant) {
- Global("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("determinant", "var");
diff --git a/src/tint/writer/msl/generator_impl_loop_test.cc b/src/tint/writer/msl/generator_impl_loop_test.cc
index 85f1deb..50b69d0 100644
--- a/src/tint/writer/msl/generator_impl_loop_test.cc
+++ b/src/tint/writer/msl/generator_impl_loop_test.cc
@@ -64,8 +64,8 @@
TEST_F(MslGeneratorImplTest, Emit_LoopNestedWithContinuing) {
Func("a_statement", {}, ty.void_(), {});
- Global("lhs", ty.f32(), ast::StorageClass::kPrivate);
- Global("rhs", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("lhs", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
auto* body = Block(create<ast::DiscardStatement>());
auto* continuing = Block(CallStmt(Call("a_statement")));
@@ -107,7 +107,7 @@
// }
//
- Global("rhs", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4_f))), //
Decl(Var("other", ty.f32())), //
@@ -184,7 +184,7 @@
Func("f", {Param("i", ty.i32())}, ty.void_(), {});
auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
- Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
auto* multi_stmt = Block(f(1_i), f(2_i));
auto* loop = For(multi_stmt, nullptr, nullptr, //
Block(Return()));
@@ -260,7 +260,7 @@
Func("f", {Param("i", ty.i32())}, ty.void_(), {});
auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
- Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
auto* multi_stmt = Block(f(1_i), f(2_i));
auto* loop = For(nullptr, nullptr, multi_stmt, //
Block(Return()));
@@ -315,7 +315,7 @@
Func("f", {Param("i", ty.i32())}, ty.void_(), {});
auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
- Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
auto* multi_stmt_a = Block(f(1_i), f(2_i));
auto* multi_stmt_b = Block(f(3_i), f(4_i));
auto* loop = For(multi_stmt_a, Expr(true), multi_stmt_b, //
diff --git a/src/tint/writer/msl/generator_impl_member_accessor_test.cc b/src/tint/writer/msl/generator_impl_member_accessor_test.cc
index c9f3da0..96824a1 100644
--- a/src/tint/writer/msl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/msl/generator_impl_member_accessor_test.cc
@@ -20,8 +20,8 @@
using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor) {
- Global("str", ty.Of(Structure("my_str", {Member("mem", ty.f32())})),
- ast::StorageClass::kPrivate);
+ GlobalVar("str", ty.Of(Structure("my_str", {Member("mem", ty.f32())})),
+ ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("str", "mem");
WrapInFunction(expr);
@@ -33,7 +33,7 @@
}
TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor_Swizzle_xyz) {
- Global("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("my_vec", "xyz");
WrapInFunction(expr);
@@ -45,7 +45,7 @@
}
TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor_Swizzle_gbr) {
- Global("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("my_vec", "gbr");
WrapInFunction(expr);
diff --git a/src/tint/writer/msl/generator_impl_module_constant_test.cc b/src/tint/writer/msl/generator_impl_module_constant_test.cc
index f23e51a..c204686 100644
--- a/src/tint/writer/msl/generator_impl_module_constant_test.cc
+++ b/src/tint/writer/msl/generator_impl_module_constant_test.cc
@@ -22,16 +22,254 @@
using MslGeneratorImplTest = TestHelper;
-TEST_F(MslGeneratorImplTest, Emit_ModuleConstant) {
- auto* var = GlobalConst("pos", ty.array<f32, 3>(), array<f32, 3>(1_f, 2_f, 3_f));
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_AInt) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
- ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
- EXPECT_EQ(gen.result(), "constant float pos[3] = {1.0f, 2.0f, 3.0f};\n");
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ int const l = 1;
}
-TEST_F(MslGeneratorImplTest, Emit_SpecConstant) {
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_AFloat) {
+ auto* var = GlobalConst("G", nullptr, Expr(1._a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float const l = 1.0f;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_i32) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_i));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ int const l = 1;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_u32) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_u));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ uint const l = 1u;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_f32) {
+ auto* var = GlobalConst("G", nullptr, Expr(1_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float const l = 1.0f;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_AInt) {
+ auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ int3 const l = int3(1, 2, 3);
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_AFloat) {
+ auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float3 const l = float3(1.0f, 2.0f, 3.0f);
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_f32) {
+ auto* var = GlobalConst("G", nullptr, vec3<f32>(1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float3 const l = float3(1.0f, 2.0f, 3.0f);
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_mat2x3_AFloat) {
+ auto* var = GlobalConst("G", nullptr,
+ Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float2x3 const l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_mat2x3_f32) {
+ auto* var = GlobalConst("G", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float2x3 const l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_arr_f32) {
+ auto* var = GlobalConst("G", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+void f() {
+ tint_array<float, 3> const l = tint_array<float, 3>{1.0f, 2.0f, 3.0f};
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_GlobalConst_arr_vec2_bool) {
+ auto* var = GlobalConst("G", nullptr,
+ Construct(ty.array(ty.vec2<bool>(), 3_u), //
+ vec2<bool>(true, false), //
+ vec2<bool>(false, true), //
+ vec2<bool>(true, true)));
+ Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+void f() {
+ tint_array<bool2, 3> const l = tint_array<bool2, 3>{bool2(true, false), bool2(false, true), bool2(true)};
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_Override) {
auto* var = Override("pos", ty.f32(), Expr(3_f),
ast::AttributeList{
Id(23),
@@ -43,7 +281,7 @@
EXPECT_EQ(gen.result(), "constant float pos [[function_constant(23)]];\n");
}
-TEST_F(MslGeneratorImplTest, Emit_SpecConstant_NoId) {
+TEST_F(MslGeneratorImplTest, Emit_Override_NoId) {
auto* var_a = Override("a", ty.f32(), nullptr,
ast::AttributeList{
Id(0),
diff --git a/src/tint/writer/msl/generator_impl_sanitizer_test.cc b/src/tint/writer/msl/generator_impl_sanitizer_test.cc
index 475025c..1514373 100644
--- a/src/tint/writer/msl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/msl/generator_impl_sanitizer_test.cc
@@ -27,11 +27,11 @@
TEST_F(MslSanitizerTest, Call_ArrayLength) {
auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
{
@@ -50,12 +50,25 @@
auto* expect = R"(#include <metal_stdlib>
using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
struct tint_symbol {
- /* 0x0000 */ uint4 buffer_size[1];
+ /* 0x0000 */ tint_array<uint4, 1> buffer_size;
};
struct my_struct {
- float a[1];
+ tint_array<float, 1> a;
};
fragment void a_func(const constant tint_symbol* tint_symbol_2 [[buffer(30)]]) {
@@ -72,11 +85,11 @@
Member(0, "z", ty.f32()),
Member(4, "a", ty.array<f32>(4)),
});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
{
@@ -95,13 +108,26 @@
auto* expect = R"(#include <metal_stdlib>
using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
struct tint_symbol {
- /* 0x0000 */ uint4 buffer_size[1];
+ /* 0x0000 */ tint_array<uint4, 1> buffer_size;
};
struct my_struct {
float z;
- float a[1];
+ tint_array<float, 1> a;
};
fragment void a_func(const constant tint_symbol* tint_symbol_2 [[buffer(30)]]) {
@@ -116,11 +142,11 @@
TEST_F(MslSanitizerTest, Call_ArrayLength_ViaLets) {
auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
auto* p = Let("p", nullptr, AddressOf("b"));
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
@@ -143,12 +169,25 @@
auto* expect = R"(#include <metal_stdlib>
using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
struct tint_symbol {
- /* 0x0000 */ uint4 buffer_size[1];
+ /* 0x0000 */ tint_array<uint4, 1> buffer_size;
};
struct my_struct {
- float a[1];
+ tint_array<float, 1> a;
};
fragment void a_func(const constant tint_symbol* tint_symbol_2 [[buffer(30)]]) {
@@ -163,16 +202,16 @@
TEST_F(MslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniform) {
auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(0),
- });
- Global("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(2),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(0u),
+ });
+ GlobalVar("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(2u),
+ create<ast::GroupAttribute>(0u),
+ });
Func("a_func", {}, ty.void_(),
{
@@ -196,12 +235,25 @@
auto* expect = R"(#include <metal_stdlib>
using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
struct tint_symbol {
- /* 0x0000 */ uint4 buffer_size[2];
+ /* 0x0000 */ tint_array<uint4, 2> buffer_size;
};
struct my_struct {
- float a[1];
+ tint_array<float, 1> a;
};
fragment void a_func(const constant tint_symbol* tint_symbol_2 [[buffer(29)]]) {
@@ -215,16 +267,16 @@
TEST_F(MslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniformMissingBinding) {
auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(0),
- });
- Global("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(2),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(0u),
+ });
+ GlobalVar("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(2u),
+ create<ast::GroupAttribute>(0u),
+ });
Func("a_func", {}, ty.void_(),
{
diff --git a/src/tint/writer/msl/generator_impl_test.cc b/src/tint/writer/msl/generator_impl_test.cc
index 183fef5..aec9bfb 100644
--- a/src/tint/writer/msl/generator_impl_test.cc
+++ b/src/tint/writer/msl/generator_impl_test.cc
@@ -141,7 +141,7 @@
}
TEST_F(MslGeneratorImplTest, WorkgroupMatrix) {
- Global("m", ty.mat2x2<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("m", ty.mat2x2<f32>(), ast::StorageClass::kWorkgroup);
Func("comp_main", {}, ty.void_(), {Decl(Let("x", nullptr, Expr("m")))},
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
@@ -178,7 +178,7 @@
}
TEST_F(MslGeneratorImplTest, WorkgroupMatrixInArray) {
- Global("m", ty.array(ty.mat2x2<f32>(), 4_i), ast::StorageClass::kWorkgroup);
+ GlobalVar("m", ty.array(ty.mat2x2<f32>(), 4_i), ast::StorageClass::kWorkgroup);
Func("comp_main", {}, ty.void_(), {Decl(Let("x", nullptr, Expr("m")))},
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
@@ -188,25 +188,34 @@
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
-struct tint_array_wrapper {
- float2x2 arr[4];
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
};
struct tint_symbol_3 {
- tint_array_wrapper m;
+ tint_array<float2x2, 4> m;
};
-void comp_main_inner(uint local_invocation_index, threadgroup tint_array_wrapper* const tint_symbol) {
+void comp_main_inner(uint local_invocation_index, threadgroup tint_array<float2x2, 4>* const tint_symbol) {
for(uint idx = local_invocation_index; (idx < 4u); idx = (idx + 1u)) {
uint const i = idx;
- (*(tint_symbol)).arr[i] = float2x2(float2(0.0f), float2(0.0f));
+ (*(tint_symbol))[i] = float2x2(float2(0.0f), float2(0.0f));
}
threadgroup_barrier(mem_flags::mem_threadgroup);
- tint_array_wrapper const x = *(tint_symbol);
+ tint_array<float2x2, 4> const x = *(tint_symbol);
}
kernel void comp_main(threadgroup tint_symbol_3* tint_symbol_2 [[threadgroup(0)]], uint local_invocation_index [[thread_index_in_threadgroup]]) {
- threadgroup tint_array_wrapper* const tint_symbol_1 = &((*(tint_symbol_2)).m);
+ threadgroup tint_array<float2x2, 4>* const tint_symbol_1 = &((*(tint_symbol_2)).m);
comp_main_inner(local_invocation_index, tint_symbol_1);
return;
}
@@ -227,7 +236,7 @@
Structure("S2", {
Member("s", ty.type_name("S1")),
});
- Global("s", ty.type_name("S2"), ast::StorageClass::kWorkgroup);
+ GlobalVar("s", ty.type_name("S2"), ast::StorageClass::kWorkgroup);
Func("comp_main", {}, ty.void_(), {Decl(Let("x", nullptr, Expr("s")))},
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
@@ -274,15 +283,15 @@
}
TEST_F(MslGeneratorImplTest, WorkgroupMatrix_Multiples) {
- Global("m1", ty.mat2x2<f32>(), ast::StorageClass::kWorkgroup);
- Global("m2", ty.mat2x3<f32>(), ast::StorageClass::kWorkgroup);
- Global("m3", ty.mat2x4<f32>(), ast::StorageClass::kWorkgroup);
- Global("m4", ty.mat3x2<f32>(), ast::StorageClass::kWorkgroup);
- Global("m5", ty.mat3x3<f32>(), ast::StorageClass::kWorkgroup);
- Global("m6", ty.mat3x4<f32>(), ast::StorageClass::kWorkgroup);
- Global("m7", ty.mat4x2<f32>(), ast::StorageClass::kWorkgroup);
- Global("m8", ty.mat4x3<f32>(), ast::StorageClass::kWorkgroup);
- Global("m9", ty.mat4x4<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("m1", ty.mat2x2<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("m2", ty.mat2x3<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("m3", ty.mat2x4<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("m4", ty.mat3x2<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("m5", ty.mat3x3<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("m6", ty.mat3x4<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("m7", ty.mat4x2<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("m8", ty.mat4x3<f32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("m9", ty.mat4x4<f32>(), ast::StorageClass::kWorkgroup);
Func("main1", {}, ty.void_(),
{
Decl(Let("a1", nullptr, Expr("m1"))),
diff --git a/src/tint/writer/msl/generator_impl_type_test.cc b/src/tint/writer/msl/generator_impl_type_test.cc
index 257468b..070b1bb 100644
--- a/src/tint/writer/msl/generator_impl_type_test.cc
+++ b/src/tint/writer/msl/generator_impl_type_test.cc
@@ -31,6 +31,20 @@
namespace tint::writer::msl {
namespace {
+void FormatMSLField(std::stringstream& out,
+ const char* addr,
+ const char* type,
+ size_t array_count,
+ const char* name) {
+ out << " /* " << std::string(addr) << " */ ";
+ if (array_count == 0) {
+ out << type << " ";
+ } else {
+ out << "tint_array<" << type << ", " << std::to_string(array_count) << "> ";
+ }
+ out << name << ";\n";
+}
+
#define CHECK_TYPE_SIZE_AND_ALIGN(TYPE, SIZE, ALIGN) \
static_assert(sizeof(TYPE) == SIZE, "Bad type size"); \
static_assert(alignof(TYPE) == ALIGN, "Bad type alignment")
@@ -63,60 +77,60 @@
TEST_F(MslGeneratorImplTest, EmitType_Array) {
auto* arr = ty.array<bool, 4>();
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
std::stringstream out;
ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), "ary")) << gen.error();
- EXPECT_EQ(out.str(), "bool ary[4]");
+ EXPECT_EQ(out.str(), "tint_array<bool, 4>");
}
TEST_F(MslGeneratorImplTest, EmitType_ArrayOfArray) {
auto* a = ty.array<bool, 4>();
auto* b = ty.array(a, 5_u);
- Global("G", b, ast::StorageClass::kPrivate);
+ GlobalVar("G", b, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
std::stringstream out;
ASSERT_TRUE(gen.EmitType(out, program->TypeOf(b), "ary")) << gen.error();
- EXPECT_EQ(out.str(), "bool ary[5][4]");
+ EXPECT_EQ(out.str(), "tint_array<tint_array<bool, 4>, 5>");
}
TEST_F(MslGeneratorImplTest, EmitType_ArrayOfArrayOfArray) {
auto* a = ty.array<bool, 4>();
auto* b = ty.array(a, 5_u);
auto* c = ty.array(b, 6_u);
- Global("G", c, ast::StorageClass::kPrivate);
+ GlobalVar("G", c, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
std::stringstream out;
ASSERT_TRUE(gen.EmitType(out, program->TypeOf(c), "ary")) << gen.error();
- EXPECT_EQ(out.str(), "bool ary[6][5][4]");
+ EXPECT_EQ(out.str(), "tint_array<tint_array<tint_array<bool, 4>, 5>, 6>");
}
TEST_F(MslGeneratorImplTest, EmitType_Array_WithoutName) {
auto* arr = ty.array<bool, 4>();
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
std::stringstream out;
ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), "")) << gen.error();
- EXPECT_EQ(out.str(), "bool[4]");
+ EXPECT_EQ(out.str(), "tint_array<bool, 4>");
}
TEST_F(MslGeneratorImplTest, EmitType_RuntimeArray) {
auto* arr = ty.array<bool, 1>();
- Global("G", arr, ast::StorageClass::kPrivate);
+ GlobalVar("G", arr, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
std::stringstream out;
ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), "ary")) << gen.error();
- EXPECT_EQ(out.str(), "bool ary[1]");
+ EXPECT_EQ(out.str(), "tint_array<bool, 1>");
}
TEST_F(MslGeneratorImplTest, EmitType_Bool) {
@@ -233,11 +247,11 @@
Member("z", ty.f32()),
});
- Global("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -245,54 +259,58 @@
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.error();
- // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, NAME, SUFFIX)
+ // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, ARRAY_COUNT, NAME)
// for each field of the structure s.
-#define ALL_FIELDS() \
- FIELD(0x0000, int, a, /*NO SUFFIX*/) \
- FIELD(0x0004, int8_t, tint_pad, [124]) \
- FIELD(0x0080, float, b, /*NO SUFFIX*/) \
- FIELD(0x0084, int8_t, tint_pad_1, [124]) \
- FIELD(0x0100, float2, c, /*NO SUFFIX*/) \
- FIELD(0x0108, uint, d, /*NO SUFFIX*/) \
- FIELD(0x010c, int8_t, tint_pad_2, [4]) \
- FIELD(0x0110, packed_float3, e, /*NO SUFFIX*/) \
- FIELD(0x011c, uint, f, /*NO SUFFIX*/) \
- FIELD(0x0120, float4, g, /*NO SUFFIX*/) \
- FIELD(0x0130, uint, h, /*NO SUFFIX*/) \
- FIELD(0x0134, int8_t, tint_pad_3, [4]) \
- FIELD(0x0138, float2x2, i, /*NO SUFFIX*/) \
- FIELD(0x0148, uint, j, /*NO SUFFIX*/) \
- FIELD(0x014c, int8_t, tint_pad_4, [4]) \
- FIELD(0x0150, float2x3, k, /*NO SUFFIX*/) \
- FIELD(0x0170, uint, l, /*NO SUFFIX*/) \
- FIELD(0x0174, int8_t, tint_pad_5, [12]) \
- FIELD(0x0180, float2x4, m, /*NO SUFFIX*/) \
- FIELD(0x01a0, uint, n, /*NO SUFFIX*/) \
- FIELD(0x01a4, int8_t, tint_pad_6, [4]) \
- FIELD(0x01a8, float3x2, o, /*NO SUFFIX*/) \
- FIELD(0x01c0, uint, p, /*NO SUFFIX*/) \
- FIELD(0x01c4, int8_t, tint_pad_7, [12]) \
- FIELD(0x01d0, float3x3, q, /*NO SUFFIX*/) \
- FIELD(0x0200, uint, r, /*NO SUFFIX*/) \
- FIELD(0x0204, int8_t, tint_pad_8, [12]) \
- FIELD(0x0210, float3x4, s, /*NO SUFFIX*/) \
- FIELD(0x0240, uint, t, /*NO SUFFIX*/) \
- FIELD(0x0244, int8_t, tint_pad_9, [4]) \
- FIELD(0x0248, float4x2, u, /*NO SUFFIX*/) \
- FIELD(0x0268, uint, v, /*NO SUFFIX*/) \
- FIELD(0x026c, int8_t, tint_pad_10, [4]) \
- FIELD(0x0270, float4x3, w, /*NO SUFFIX*/) \
- FIELD(0x02b0, uint, x, /*NO SUFFIX*/) \
- FIELD(0x02b4, int8_t, tint_pad_11, [12]) \
- FIELD(0x02c0, float4x4, y, /*NO SUFFIX*/) \
- FIELD(0x0300, float, z, /*NO SUFFIX*/) \
- FIELD(0x0304, int8_t, tint_pad_12, [124])
+#define ALL_FIELDS() \
+ FIELD(0x0000, int, 0, a) \
+ FIELD(0x0004, int8_t, 124, tint_pad) \
+ FIELD(0x0080, float, 0, b) \
+ FIELD(0x0084, int8_t, 124, tint_pad_1) \
+ FIELD(0x0100, float2, 0, c) \
+ FIELD(0x0108, uint, 0, d) \
+ FIELD(0x010c, int8_t, 4, tint_pad_2) \
+ FIELD(0x0110, packed_float3, 0, e) \
+ FIELD(0x011c, uint, 0, f) \
+ FIELD(0x0120, float4, 0, g) \
+ FIELD(0x0130, uint, 0, h) \
+ FIELD(0x0134, int8_t, 4, tint_pad_3) \
+ FIELD(0x0138, float2x2, 0, i) \
+ FIELD(0x0148, uint, 0, j) \
+ FIELD(0x014c, int8_t, 4, tint_pad_4) \
+ FIELD(0x0150, float2x3, 0, k) \
+ FIELD(0x0170, uint, 0, l) \
+ FIELD(0x0174, int8_t, 12, tint_pad_5) \
+ FIELD(0x0180, float2x4, 0, m) \
+ FIELD(0x01a0, uint, 0, n) \
+ FIELD(0x01a4, int8_t, 4, tint_pad_6) \
+ FIELD(0x01a8, float3x2, 0, o) \
+ FIELD(0x01c0, uint, 0, p) \
+ FIELD(0x01c4, int8_t, 12, tint_pad_7) \
+ FIELD(0x01d0, float3x3, 0, q) \
+ FIELD(0x0200, uint, 0, r) \
+ FIELD(0x0204, int8_t, 12, tint_pad_8) \
+ FIELD(0x0210, float3x4, 0, s) \
+ FIELD(0x0240, uint, 0, t) \
+ FIELD(0x0244, int8_t, 4, tint_pad_9) \
+ FIELD(0x0248, float4x2, 0, u) \
+ FIELD(0x0268, uint, 0, v) \
+ FIELD(0x026c, int8_t, 4, tint_pad_10) \
+ FIELD(0x0270, float4x3, 0, w) \
+ FIELD(0x02b0, uint, 0, x) \
+ FIELD(0x02b4, int8_t, 12, tint_pad_11) \
+ FIELD(0x02c0, float4x4, 0, y) \
+ FIELD(0x0300, float, 0, z) \
+ FIELD(0x0304, int8_t, 124, tint_pad_12)
// Check that the generated string is as expected.
-#define FIELD(ADDR, TYPE, NAME, SUFFIX) " /* " #ADDR " */ " #TYPE " " #NAME #SUFFIX ";\n"
- auto* expect = "struct S {\n" ALL_FIELDS() "};\n";
+ std::stringstream expect;
+ expect << "struct S {\n";
+#define FIELD(ADDR, TYPE, ARRAY_COUNT, NAME) \
+ FormatMSLField(expect, #ADDR, #TYPE, ARRAY_COUNT, #NAME);
+ ALL_FIELDS()
#undef FIELD
- EXPECT_EQ(buf.String(), expect);
+ expect << "};\n";
+ EXPECT_EQ(buf.String(), expect.str());
// 1.4 Metal and C++14
// The Metal programming language is a C++14-based Specification with
@@ -304,12 +322,12 @@
// layout is as expected for C++14 / MSL.
{
struct S {
-#define FIELD(ADDR, TYPE, NAME, SUFFIX) TYPE NAME SUFFIX;
+#define FIELD(ADDR, TYPE, ARRAY_COUNT, NAME) std::array<TYPE, ARRAY_COUNT ? ARRAY_COUNT : 1> NAME;
ALL_FIELDS()
#undef FIELD
};
-#define FIELD(ADDR, TYPE, NAME, SUFFIX) \
+#define FIELD(ADDR, TYPE, ARRAY_COUNT, NAME) \
EXPECT_EQ(ADDR, static_cast<int>(offsetof(S, NAME))) << "Field " << #NAME;
ALL_FIELDS()
#undef FIELD
@@ -338,11 +356,11 @@
Member("e", ty.f32()),
});
- Global("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -350,22 +368,26 @@
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.error();
- // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, NAME, SUFFIX)
+ // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, ARRAY_COUNT, NAME)
// for each field of the structure s.
-#define ALL_FIELDS() \
- FIELD(0x0000, int, a, /*NO SUFFIX*/) \
- FIELD(0x0004, int8_t, tint_pad, [508]) \
- FIELD(0x0200, inner_x, b, /*NO SUFFIX*/) \
- FIELD(0x0600, float, c, /*NO SUFFIX*/) \
- FIELD(0x0604, inner_y, d, /*NO SUFFIX*/) \
- FIELD(0x0808, float, e, /*NO SUFFIX*/) \
- FIELD(0x080c, int8_t, tint_pad_1, [500])
+#define ALL_FIELDS() \
+ FIELD(0x0000, int, 0, a) \
+ FIELD(0x0004, int8_t, 508, tint_pad) \
+ FIELD(0x0200, inner_x, 0, b) \
+ FIELD(0x0600, float, 0, c) \
+ FIELD(0x0604, inner_y, 0, d) \
+ FIELD(0x0808, float, 0, e) \
+ FIELD(0x080c, int8_t, 500, tint_pad_1)
// Check that the generated string is as expected.
-#define FIELD(ADDR, TYPE, NAME, SUFFIX) " /* " #ADDR " */ " #TYPE " " #NAME #SUFFIX ";\n"
- auto* expect = "struct S {\n" ALL_FIELDS() "};\n";
+ std::stringstream expect;
+ expect << "struct S {\n";
+#define FIELD(ADDR, TYPE, ARRAY_COUNT, NAME) \
+ FormatMSLField(expect, #ADDR, #TYPE, ARRAY_COUNT, #NAME);
+ ALL_FIELDS()
#undef FIELD
- EXPECT_EQ(buf.String(), expect);
+ expect << "};\n";
+ EXPECT_EQ(buf.String(), expect.str());
// 1.4 Metal and C++14
// The Metal programming language is a C++14-based Specification with
@@ -389,12 +411,12 @@
CHECK_TYPE_SIZE_AND_ALIGN(inner_y, 516, 4);
struct S {
-#define FIELD(ADDR, TYPE, NAME, SUFFIX) TYPE NAME SUFFIX;
+#define FIELD(ADDR, TYPE, ARRAY_COUNT, NAME) std::array<TYPE, ARRAY_COUNT ? ARRAY_COUNT : 1> NAME;
ALL_FIELDS()
#undef FIELD
};
-#define FIELD(ADDR, TYPE, NAME, SUFFIX) \
+#define FIELD(ADDR, TYPE, ARRAY_COUNT, NAME) \
EXPECT_EQ(ADDR, static_cast<int>(offsetof(S, NAME))) << "Field " << #NAME;
ALL_FIELDS()
#undef FIELD
@@ -428,11 +450,11 @@
Member("f", array_z),
});
- Global("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -440,23 +462,27 @@
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.error();
- // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, NAME, SUFFIX)
+ // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, ARRAY_COUNT, NAME)
// for each field of the structure s.
-#define ALL_FIELDS() \
- FIELD(0x0000, int, a, /*NO SUFFIX*/) \
- FIELD(0x0004, float, b, [7]) \
- FIELD(0x0020, float, c, /*NO SUFFIX*/) \
- FIELD(0x0024, int8_t, tint_pad, [476]) \
- FIELD(0x0200, inner, d, [4]) \
- FIELD(0x1200, float, e, /*NO SUFFIX*/) \
- FIELD(0x1204, float, f, [1]) \
- FIELD(0x1208, int8_t, tint_pad_1, [504])
+#define ALL_FIELDS() \
+ FIELD(0x0000, int, 0, a) \
+ FIELD(0x0004, float, 7, b) \
+ FIELD(0x0020, float, 0, c) \
+ FIELD(0x0024, int8_t, 476, tint_pad) \
+ FIELD(0x0200, inner, 4, d) \
+ FIELD(0x1200, float, 0, e) \
+ FIELD(0x1204, float, 1, f) \
+ FIELD(0x1208, int8_t, 504, tint_pad_1)
// Check that the generated string is as expected.
-#define FIELD(ADDR, TYPE, NAME, SUFFIX) " /* " #ADDR " */ " #TYPE " " #NAME #SUFFIX ";\n"
- auto* expect = "struct S {\n" ALL_FIELDS() "};\n";
+ std::stringstream expect;
+ expect << "struct S {\n";
+#define FIELD(ADDR, TYPE, ARRAY_COUNT, NAME) \
+ FormatMSLField(expect, #ADDR, #TYPE, ARRAY_COUNT, #NAME);
+ ALL_FIELDS()
#undef FIELD
- EXPECT_EQ(buf.String(), expect);
+ expect << "};\n";
+ EXPECT_EQ(buf.String(), expect.str());
// 1.4 Metal and C++14
// The Metal programming language is a C++14-based Specification with
@@ -486,12 +512,12 @@
CHECK_TYPE_SIZE_AND_ALIGN(array_z, 4, 4);
struct S {
-#define FIELD(ADDR, TYPE, NAME, SUFFIX) TYPE NAME SUFFIX;
+#define FIELD(ADDR, TYPE, ARRAY_COUNT, NAME) std::array<TYPE, ARRAY_COUNT ? ARRAY_COUNT : 1> NAME;
ALL_FIELDS()
#undef FIELD
};
-#define FIELD(ADDR, TYPE, NAME, SUFFIX) \
+#define FIELD(ADDR, TYPE, ARRAY_COUNT, NAME) \
EXPECT_EQ(ADDR, static_cast<int>(offsetof(S, NAME))) << "Field " << #NAME;
ALL_FIELDS()
#undef FIELD
@@ -510,11 +536,11 @@
Member("c", ty.i32()),
});
- Global("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -522,20 +548,24 @@
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.error();
- // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, NAME, SUFFIX)
+ // ALL_FIELDS() calls the macro FIELD(ADDR, TYPE, ARRAY_COUNT, NAME)
// for each field of the structure s.
-#define ALL_FIELDS() \
- FIELD(0x0000, int, a, /*NO SUFFIX*/) \
- FIELD(0x0004, int8_t, tint_pad, [12]) \
- FIELD(0x0010, float3, b, [4]) \
- FIELD(0x0050, int, c, /*NO SUFFIX*/) \
- FIELD(0x0054, int8_t, tint_pad_1, [12])
+#define ALL_FIELDS() \
+ FIELD(0x0000, int, 0, a) \
+ FIELD(0x0004, int8_t, 12, tint_pad) \
+ FIELD(0x0010, float3, 4, b) \
+ FIELD(0x0050, int, 0, c) \
+ FIELD(0x0054, int8_t, 12, tint_pad_1)
// Check that the generated string is as expected.
-#define FIELD(ADDR, TYPE, NAME, SUFFIX) " /* " #ADDR " */ " #TYPE " " #NAME #SUFFIX ";\n"
- auto* expect = "struct S {\n" ALL_FIELDS() "};\n";
+ std::stringstream expect;
+ expect << "struct S {\n";
+#define FIELD(ADDR, TYPE, ARRAY_COUNT, NAME) \
+ FormatMSLField(expect, #ADDR, #TYPE, ARRAY_COUNT, #NAME);
+ ALL_FIELDS()
#undef FIELD
- EXPECT_EQ(buf.String(), expect);
+ expect << "};\n";
+ EXPECT_EQ(buf.String(), expect.str());
}
TEST_F(MslGeneratorImplTest, AttemptTintPadSymbolCollision) {
@@ -570,11 +600,11 @@
Member("tint_pad_21", ty.f32()),
});
- Global("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -583,44 +613,44 @@
ASSERT_TRUE(gen.EmitStructType(&buf, sem_s)) << gen.error();
EXPECT_EQ(buf.String(), R"(struct S {
/* 0x0000 */ int tint_pad_2;
- /* 0x0004 */ int8_t tint_pad_10[124];
+ /* 0x0004 */ tint_array<int8_t, 124> tint_pad_10;
/* 0x0080 */ float tint_pad_20;
- /* 0x0084 */ int8_t tint_pad_11[124];
+ /* 0x0084 */ tint_array<int8_t, 124> tint_pad_11;
/* 0x0100 */ float2 tint_pad_33;
/* 0x0108 */ uint tint_pad_1;
- /* 0x010c */ int8_t tint_pad_12[4];
+ /* 0x010c */ tint_array<int8_t, 4> tint_pad_12;
/* 0x0110 */ packed_float3 tint_pad_3;
/* 0x011c */ uint tint_pad_7;
/* 0x0120 */ float4 tint_pad_25;
/* 0x0130 */ uint tint_pad_5;
- /* 0x0134 */ int8_t tint_pad_13[4];
+ /* 0x0134 */ tint_array<int8_t, 4> tint_pad_13;
/* 0x0138 */ float2x2 tint_pad_27;
/* 0x0148 */ uint tint_pad_24;
- /* 0x014c */ int8_t tint_pad_14[4];
+ /* 0x014c */ tint_array<int8_t, 4> tint_pad_14;
/* 0x0150 */ float2x3 tint_pad_23;
/* 0x0170 */ uint tint_pad;
- /* 0x0174 */ int8_t tint_pad_15[12];
+ /* 0x0174 */ tint_array<int8_t, 12> tint_pad_15;
/* 0x0180 */ float2x4 tint_pad_8;
/* 0x01a0 */ uint tint_pad_26;
- /* 0x01a4 */ int8_t tint_pad_16[4];
+ /* 0x01a4 */ tint_array<int8_t, 4> tint_pad_16;
/* 0x01a8 */ float3x2 tint_pad_29;
/* 0x01c0 */ uint tint_pad_6;
- /* 0x01c4 */ int8_t tint_pad_17[12];
+ /* 0x01c4 */ tint_array<int8_t, 12> tint_pad_17;
/* 0x01d0 */ float3x3 tint_pad_22;
/* 0x0200 */ uint tint_pad_32;
- /* 0x0204 */ int8_t tint_pad_18[12];
+ /* 0x0204 */ tint_array<int8_t, 12> tint_pad_18;
/* 0x0210 */ float3x4 tint_pad_34;
/* 0x0240 */ uint tint_pad_35;
- /* 0x0244 */ int8_t tint_pad_19[4];
+ /* 0x0244 */ tint_array<int8_t, 4> tint_pad_19;
/* 0x0248 */ float4x2 tint_pad_30;
/* 0x0268 */ uint tint_pad_9;
- /* 0x026c */ int8_t tint_pad_36[4];
+ /* 0x026c */ tint_array<int8_t, 4> tint_pad_36;
/* 0x0270 */ float4x3 tint_pad_31;
/* 0x02b0 */ uint tint_pad_28;
- /* 0x02b4 */ int8_t tint_pad_37[12];
+ /* 0x02b4 */ tint_array<int8_t, 12> tint_pad_37;
/* 0x02c0 */ float4x4 tint_pad_4;
/* 0x0300 */ float tint_pad_21;
- /* 0x0304 */ int8_t tint_pad_38[124];
+ /* 0x0304 */ tint_array<int8_t, 124> tint_pad_38;
};
)");
}
@@ -631,11 +661,11 @@
Member("b", ty.f32()),
});
- Global("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -798,11 +828,11 @@
auto params = GetParam();
auto* s = ty.storage_texture(params.dim, ast::TexelFormat::kR32Float, ast::Access::kWrite);
- Global("test_var", s,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("test_var", s,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_unary_op_test.cc b/src/tint/writer/msl/generator_impl_unary_op_test.cc
index a1aecd9..843e2a4 100644
--- a/src/tint/writer/msl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/msl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
using MslUnaryOpTest = TestHelper;
TEST_F(MslUnaryOpTest, AddressOf) {
- Global("expr", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.f32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
WrapInFunction(op);
@@ -32,7 +32,7 @@
}
TEST_F(MslUnaryOpTest, Complement) {
- Global("expr", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.i32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
WrapInFunction(op);
@@ -44,7 +44,7 @@
}
TEST_F(MslUnaryOpTest, Indirection) {
- Global("G", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("G", ty.f32(), ast::StorageClass::kPrivate);
auto* p =
Let("expr", nullptr, create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
@@ -58,7 +58,7 @@
}
TEST_F(MslUnaryOpTest, Not) {
- Global("expr", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.bool_(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
WrapInFunction(op);
@@ -70,7 +70,7 @@
}
TEST_F(MslUnaryOpTest, Negation) {
- Global("expr", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.i32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
WrapInFunction(op);
diff --git a/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
index e41cc3b..46becb0 100644
--- a/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
@@ -38,7 +38,7 @@
EXPECT_EQ(gen.result(), " float a = 0.0f;\n");
}
-TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Let) {
auto* var = Let("a", ty.f32(), Construct(ty.f32()));
auto* stmt = Decl(var);
WrapInFunction(stmt);
@@ -51,6 +51,266 @@
EXPECT_EQ(gen.result(), " float const a = 0.0f;\n");
}
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
+ auto* var = Const("a", ty.f32(), Construct(ty.f32()));
+ auto* stmt = Decl(var);
+ WrapInFunction(stmt);
+
+ GeneratorImpl& gen = Build();
+
+ gen.increment_indent();
+
+ ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
+ EXPECT_EQ(gen.result(), ""); // Not a mistake - 'const' is inlined
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_AInt) {
+ auto* C = Const("C", nullptr, Expr(1_a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ int const l = 1;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_AFloat) {
+ auto* C = Const("C", nullptr, Expr(1._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float const l = 1.0f;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_i32) {
+ auto* C = Const("C", nullptr, Expr(1_i));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ int const l = 1;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_u32) {
+ auto* C = Const("C", nullptr, Expr(1_u));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ uint const l = 1u;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_f32) {
+ auto* C = Const("C", nullptr, Expr(1_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float const l = 1.0f;
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AInt) {
+ auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ int3 const l = int3(1, 2, 3);
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AFloat) {
+ auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float3 const l = float3(1.0f, 2.0f, 3.0f);
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_f32) {
+ auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float3 const l = float3(1.0f, 2.0f, 3.0f);
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
+ auto* C =
+ Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float2x3 const l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_f32) {
+ auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+ float2x3 const l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_f32) {
+ auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+void f() {
+ tint_array<float, 3> const l = tint_array<float, 3>{1.0f, 2.0f, 3.0f};
+}
+
+)");
+}
+
+TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
+ auto* C = Const("C", nullptr,
+ Construct(ty.array(ty.vec2<bool>(), 3_u), //
+ vec2<bool>(true, false), //
+ vec2<bool>(false, true), //
+ vec2<bool>(true, true)));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
+
+using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+void f() {
+ tint_array<bool2, 3> const l = tint_array<bool2, 3>{bool2(true, false), bool2(false, true), bool2(true)};
+}
+
+)");
+}
+
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Array) {
auto* var = Var("a", ty.array<f32, 5>(), ast::StorageClass::kNone);
auto* stmt = Decl(var);
@@ -61,7 +321,7 @@
gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
- EXPECT_EQ(gen.result(), " float a[5] = {0.0f};\n");
+ EXPECT_EQ(gen.result(), " tint_array<float, 5> a = {};\n");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Struct) {
@@ -111,7 +371,7 @@
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
- Global("a", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
WrapInFunction(Expr("a"));
@@ -123,20 +383,8 @@
EXPECT_THAT(gen.result(), HasSubstr("thread float tint_symbol_1 = 0.0f;\n"));
}
-TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_Private) {
- GlobalConst("initializer", ty.f32(), Expr(0_f));
- Global("a", ty.f32(), ast::StorageClass::kPrivate, Expr("initializer"));
-
- WrapInFunction(Expr("a"));
-
- GeneratorImpl& gen = SanitizeAndBuild();
-
- ASSERT_TRUE(gen.Generate()) << gen.error();
- EXPECT_THAT(gen.result(), HasSubstr("thread float tint_symbol_1 = 0.0f;\n float const tint_symbol = tint_symbol_1;\n return;\n"));
-}
-
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Workgroup) {
- Global("a", ty.f32(), ast::StorageClass::kWorkgroup);
+ GlobalVar("a", ty.f32(), ast::StorageClass::kWorkgroup);
WrapInFunction(Expr("a"));
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index 4368e3c..833324a 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -103,12 +103,18 @@
switch (builtin->Type()) {
case BuiltinType::kAcos:
return GLSLstd450Acos;
+ case BuiltinType::kAcosh:
+ return GLSLstd450Acosh;
case BuiltinType::kAsin:
return GLSLstd450Asin;
+ case BuiltinType::kAsinh:
+ return GLSLstd450Asinh;
case BuiltinType::kAtan:
return GLSLstd450Atan;
case BuiltinType::kAtan2:
return GLSLstd450Atan2;
+ case BuiltinType::kAtanh:
+ return GLSLstd450Atanh;
case BuiltinType::kCeil:
return GLSLstd450Ceil;
case BuiltinType::kClamp:
@@ -527,7 +533,7 @@
wgsize_ops.push_back(wgsize_result);
// Generate OpConstant instructions for each dimension.
- for (int i = 0; i < 3; i++) {
+ for (size_t i = 0; i < 3; i++) {
auto constant = ScalarConstant::U32(wgsize[i].value);
if (wgsize[i].overridable_const) {
// Make the constant specializable.
@@ -693,6 +699,12 @@
}
bool Builder::GenerateFunctionVariable(const ast::Variable* v) {
+ if (v->Is<ast::Const>()) {
+ // Constants are generated at their use. This is required as the 'const' declaration may be
+ // abstract-numeric, which has no SPIR-V type.
+ return true;
+ }
+
uint32_t init_id = 0;
if (v->constructor) {
init_id = GenerateExpressionWithLoadIfNeeded(v->constructor);
@@ -703,9 +715,9 @@
auto* sem = builder_.Sem().Get(v);
- if (auto* let = v->As<ast::Let>()) {
- if (!let->constructor) {
- error_ = "missing constructor for constant";
+ if (v->Is<ast::Let>()) {
+ if (!v->constructor) {
+ error_ = "missing constructor for let";
return false;
}
RegisterVariable(sem, init_id);
@@ -748,20 +760,18 @@
}
bool Builder::GenerateGlobalVariable(const ast::Variable* v) {
+ if (v->Is<ast::Const>()) {
+ // Constants are generated at their use. This is required as the 'const' declaration may be
+ // abstract-numeric, which has no SPIR-V type.
+ return true;
+ }
+
auto* sem = builder_.Sem().Get(v);
auto* type = sem->Type()->UnwrapRef();
uint32_t init_id = 0;
if (auto* ctor = v->constructor) {
- if (!v->Is<ast::Override>()) {
- auto* ctor_sem = builder_.Sem().Get(ctor);
- if (auto constant = ctor_sem->ConstantValue()) {
- init_id = GenerateConstantIfNeeded(std::move(constant));
- }
- }
- if (init_id == 0) {
- init_id = GenerateConstructorExpression(v, v->constructor);
- }
+ init_id = GenerateConstructorExpression(v, ctor);
if (init_id == 0) {
return false;
}
@@ -799,7 +809,7 @@
}
}
- if (v->IsAnyOf<ast::Let, ast::Override>()) {
+ if (v->Is<ast::Override>()) {
push_debug(spv::Op::OpName,
{Operand(init_id), Operand(builder_.Symbols().NameFor(v->symbol))});
@@ -949,7 +959,7 @@
Operand(result_type_id),
extract,
Operand(info->source_id),
- Operand(idx_constval.Element<uint32_t>(0)),
+ Operand(idx_constval->As<uint32_t>()),
})) {
return false;
}
@@ -1280,8 +1290,16 @@
uint32_t Builder::GenerateConstructorExpression(const ast::Variable* var,
const ast::Expression* expr) {
- if (auto* literal = expr->As<ast::LiteralExpression>()) {
- return GenerateLiteralIfNeeded(var, literal);
+ if (Is<ast::Override>(var)) {
+ if (auto* literal = expr->As<ast::LiteralExpression>()) {
+ return GenerateLiteralIfNeeded(var, literal);
+ }
+ } else {
+ if (auto* sem = builder_.Sem().Get(expr)) {
+ if (auto constant = sem->ConstantValue()) {
+ return GenerateConstantIfNeeded(constant);
+ }
+ }
}
if (auto* call = builder_.Sem().Get<sem::Call>(expr)) {
if (call->Target()->IsAnyOf<sem::TypeConstructor, sem::TypeConversion>()) {
@@ -1362,6 +1380,15 @@
}
}
+ if (auto* res_mat = result_type->As<sem::Matrix>()) {
+ auto* value_type = args[0]->Type()->UnwrapRef();
+ if (auto* val_mat = value_type->As<sem::Matrix>()) {
+ // Generate passthrough for matrices of the same type
+ can_cast_or_copy =
+ (res_mat->columns() == val_mat->columns()) && (res_mat->rows() == val_mat->rows());
+ }
+ }
+
if (can_cast_or_copy) {
return GenerateCastOrCopyOrPassthrough(result_type, args[0]->Declaration(), global_var);
}
@@ -1607,6 +1634,8 @@
}
return result_id;
+ } else if (from_type->Is<sem::Matrix>()) {
+ return val_id;
} else {
TINT_ICE(Writer, builder_.Diagnostics()) << "Invalid from_type";
}
@@ -1674,93 +1703,34 @@
return GenerateConstantIfNeeded(constant);
}
-uint32_t Builder::GenerateConstantIfNeeded(const sem::Constant& constant) {
- if (constant.AllZero()) {
- return GenerateConstantNullIfNeeded(constant.Type());
+uint32_t Builder::GenerateConstantIfNeeded(const sem::Constant* constant) {
+ if (constant->AllZero()) {
+ return GenerateConstantNullIfNeeded(constant->Type());
}
+ auto* ty = constant->Type();
- static constexpr size_t kOpsResultIdx = 1; // operand index of the result
- auto& global_scope = scope_stack_[0];
-
- auto gen_bool = [&](size_t element_idx) {
- bool val = constant.Element<AInt>(element_idx);
- return GenerateConstantIfNeeded(ScalarConstant::Bool(val));
- };
- auto gen_f32 = [&](size_t element_idx) {
- auto val = f32(constant.Element<AFloat>(element_idx));
- return GenerateConstantIfNeeded(ScalarConstant::F32(val.value));
- };
- auto gen_i32 = [&](size_t element_idx) {
- auto val = i32(constant.Element<AInt>(element_idx));
- return GenerateConstantIfNeeded(ScalarConstant::I32(val.value));
- };
- auto gen_u32 = [&](size_t element_idx) {
- auto val = u32(constant.Element<AInt>(element_idx));
- return GenerateConstantIfNeeded(ScalarConstant::U32(val.value));
- };
- auto gen_els = [&](std::vector<Operand>& ids, size_t start, size_t end, auto gen_el) {
- for (size_t i = start; i < end; i++) {
- auto id = gen_el(i);
- if (!id) {
- return false;
- }
- ids.emplace_back(id);
- }
- return true;
- };
- auto gen_vector = [&](const sem::Vector* ty, size_t start, size_t end) -> uint32_t {
+ auto composite = [&](size_t el_count) -> uint32_t {
auto type_id = GenerateTypeIfNeeded(ty);
if (!type_id) {
return 0;
}
+ static constexpr size_t kOpsResultIdx = 1; // operand index of the result
+
std::vector<Operand> ops;
- ops.reserve(end - start + 2);
+ ops.reserve(el_count + 2);
ops.emplace_back(type_id);
ops.push_back(Operand(0u)); // Placeholder for the result ID
- auto ok = Switch(
- constant.ElementType(), //
- [&](const sem::Bool*) { return gen_els(ops, start, end, gen_bool); }, //
- [&](const sem::F32*) { return gen_els(ops, start, end, gen_f32); }, //
- [&](const sem::I32*) { return gen_els(ops, start, end, gen_i32); }, //
- [&](const sem::U32*) { return gen_els(ops, start, end, gen_u32); }, //
- [&](Default) {
- error_ = "unhandled constant element type: " + builder_.FriendlyName(ty);
- return false;
- });
- if (!ok) {
- return 0;
- }
- return utils::GetOrCreate(global_scope.type_ctor_to_id_, OperandListKey{ops},
- [&]() -> uint32_t {
- auto result = result_op();
- ops[kOpsResultIdx] = result;
- push_type(spv::Op::OpConstantComposite, std::move(ops));
- return std::get<uint32_t>(result);
- });
- };
- auto gen_matrix = [&](const sem::Matrix* m) -> uint32_t {
- auto mat_type_id = GenerateTypeIfNeeded(m);
- if (!mat_type_id) {
- return 0;
- }
-
- std::vector<Operand> ops;
- ops.reserve(m->columns() + 2);
- ops.emplace_back(mat_type_id);
- ops.push_back(Operand(0u)); // Placeholder for the result ID
-
- for (size_t column_idx = 0; column_idx < m->columns(); column_idx++) {
- size_t start = m->rows() * column_idx;
- size_t end = m->rows() * (column_idx + 1);
- auto column_id = gen_vector(m->ColumnType(), start, end);
- if (!column_id) {
+ for (size_t i = 0; i < el_count; i++) {
+ auto id = GenerateConstantIfNeeded(constant->Index(i));
+ if (!id) {
return 0;
}
- ops.emplace_back(column_id);
+ ops.emplace_back(id);
}
+ auto& global_scope = scope_stack_[0];
return utils::GetOrCreate(global_scope.type_ctor_to_id_, OperandListKey{ops},
[&]() -> uint32_t {
auto result = result_op();
@@ -1771,15 +1741,28 @@
};
return Switch(
- constant.Type(), //
- [&](const sem::Bool*) { return gen_bool(0); }, //
- [&](const sem::F32*) { return gen_f32(0); }, //
- [&](const sem::I32*) { return gen_i32(0); }, //
- [&](const sem::U32*) { return gen_u32(0); }, //
- [&](const sem::Vector* v) { return gen_vector(v, 0, constant.ElementCount()); }, //
- [&](const sem::Matrix* m) { return gen_matrix(m); }, //
+ ty, //
+ [&](const sem::Bool*) {
+ bool val = constant->As<bool>();
+ return GenerateConstantIfNeeded(ScalarConstant::Bool(val));
+ },
+ [&](const sem::F32*) {
+ auto val = constant->As<f32>();
+ return GenerateConstantIfNeeded(ScalarConstant::F32(val.value));
+ },
+ [&](const sem::I32*) {
+ auto val = constant->As<i32>();
+ return GenerateConstantIfNeeded(ScalarConstant::I32(val.value));
+ },
+ [&](const sem::U32*) {
+ auto val = constant->As<u32>();
+ return GenerateConstantIfNeeded(ScalarConstant::U32(val.value));
+ },
+ [&](const sem::Vector* v) { return composite(v->Width()); },
+ [&](const sem::Matrix* m) { return composite(m->columns()); },
+ [&](const sem::Array* a) { return composite(a->Count()); },
[&](Default) {
- error_ = "unhandled constant type: " + builder_.FriendlyName(constant.Type());
+ error_ = "unhandled constant type: " + builder_.FriendlyName(ty);
return false;
});
}
@@ -2697,7 +2680,7 @@
// Returns the argument with the given usage
auto arg = [&](Usage usage) {
int idx = signature.IndexOf(usage);
- return (idx >= 0) ? arguments[idx] : nullptr;
+ return (idx >= 0) ? arguments[static_cast<size_t>(idx)] : nullptr;
};
// Generates the argument with the given usage, returning the operand ID
@@ -3272,7 +3255,8 @@
value,
});
case sem::BuiltinType::kAtomicCompareExchangeWeak: {
- auto comparator = GenerateExpression(call->Arguments()[1]->Declaration());
+ auto comparator =
+ GenerateExpressionWithLoadIfNeeded(call->Arguments()[1]->Declaration());
if (comparator == 0) {
return false;
}
diff --git a/src/tint/writer/spirv/builder.h b/src/tint/writer/spirv/builder.h
index 9866328..f6bb93f 100644
--- a/src/tint/writer/spirv/builder.h
+++ b/src/tint/writer/spirv/builder.h
@@ -554,7 +554,7 @@
/// Generates a constant value if needed
/// @param constant the constant to generate.
/// @returns the ID on success or 0 on failure
- uint32_t GenerateConstantIfNeeded(const sem::Constant& constant);
+ uint32_t GenerateConstantIfNeeded(const sem::Constant* constant);
/// Generates a scalar constant if needed
/// @param constant the constant to generate.
diff --git a/src/tint/writer/spirv/builder_accessor_expression_test.cc b/src/tint/writer/spirv/builder_accessor_expression_test.cc
index 2df1b65..8996b8d 100644
--- a/src/tint/writer/spirv/builder_accessor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_accessor_expression_test.cc
@@ -22,193 +22,874 @@
using BuilderTest = TestHelper;
-TEST_F(BuilderTest, IndexAccessor_VectorRef_Literal) {
- // var ary : vec3<f32>;
- // ary[1] -> ref<f32>
+TEST_F(BuilderTest, Let_IndexAccessor_Vector) {
+ // let ary = vec3<i32>(1, 2, 3);
+ // var x = ary[1i];
- auto* var = Var("ary", ty.vec3<f32>());
+ auto* ary = Let("ary", nullptr, vec3<i32>(1_i, 2_i, 3_i));
+ auto* x = Var("x", nullptr, IndexAccessor(ary, 1_i));
+ WrapInFunction(ary, x);
- auto* ary = Expr("ary");
- auto* idx_expr = Expr(1_i);
+ spirv::Builder& b = SanitizeAndBuild();
- auto* expr = IndexAccessor(ary, idx_expr);
- WrapInFunction(var, expr);
+ ASSERT_TRUE(b.Build()) << b.error();
- spirv::Builder& b = Build();
-
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
-
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 9u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Function %3
-%5 = OpConstantNull %3
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
%6 = OpTypeInt 32 1
-%7 = OpConstant %6 1
-%8 = OpTypePointer Function %4
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %5
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%9 = OpAccessChain %8 %1 %7
-)");
-}
-
-TEST_F(BuilderTest, IndexAccessor_VectorRef_Dynamic) {
- // var ary : vec3<f32>;
- // var idx : i32;
- // ary[idx] -> ref<f32>
-
- auto* var = Var("ary", ty.vec3<f32>());
- auto* idx = Var("idx", ty.i32());
-
- auto* ary = Expr("ary");
- auto* idx_expr = Expr("idx");
-
- auto* expr = IndexAccessor(ary, idx_expr);
- WrapInFunction(var, idx, expr);
-
- spirv::Builder& b = Build();
-
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(idx)) << b.error();
-
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 12u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Function %3
-%5 = OpConstantNull %3
-%8 = OpTypeInt 32 1
-%7 = OpTypePointer Function %8
-%9 = OpConstantNull %8
-%11 = OpTypePointer Function %4
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %5
-%6 = OpVariable %7 Function %9
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%10 = OpLoad %8 %6
-%12 = OpAccessChain %11 %1 %10
-)");
-}
-
-TEST_F(BuilderTest, IndexAccessor_VectorRef_Dynamic2) {
- // var ary : vec3<f32>;
- // ary[1 + 2] -> ref<f32>
-
- auto* var = Var("ary", ty.vec3<f32>());
-
- auto* ary = Expr("ary");
-
- auto* expr = IndexAccessor(ary, Add(1_i, 2_i));
- WrapInFunction(var, expr);
-
- spirv::Builder& b = Build();
-
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
-
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 11u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Function %3
-%5 = OpConstantNull %3
-%6 = OpTypeInt 32 1
+%5 = OpTypeVector %6 3
%7 = OpConstant %6 1
%8 = OpConstant %6 2
-%10 = OpTypePointer Function %4
+%9 = OpConstant %6 3
+%10 = OpConstantComposite %5 %7 %8 %9
+%13 = OpTypePointer Function %6
+%14 = OpConstantNull %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %5
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%12 = OpVariable %13 Function %14
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%9 = OpIAdd %6 %7 %8
-%11 = OpAccessChain %10 %1 %9
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%11 = OpCompositeExtract %6 %10 1
+OpStore %12 %11
+OpReturn
)");
+
+ Validate(b);
}
-TEST_F(BuilderTest, IndexAccessor_ArrayRef_MultiLevel) {
- auto* ary4 = ty.array(ty.vec3<f32>(), 4_u);
+TEST_F(BuilderTest, Const_IndexAccessor_Vector) {
+ // const ary = vec3<i32>(1, 2, 3);
+ // var x = ary[1i];
- // var ary : array<vec3<f32>, 4u>
- // ary[3i][2i];
+ auto* ary = Const("ary", nullptr, vec3<i32>(1_i, 2_i, 3_i));
+ auto* x = Var("x", nullptr, IndexAccessor(ary, 1_i));
+ WrapInFunction(ary, x);
- auto* var = Var("ary", ary4);
+ spirv::Builder& b = SanitizeAndBuild();
- auto* expr = IndexAccessor(IndexAccessor("ary", 3_i), 2_i);
- WrapInFunction(var, expr);
+ ASSERT_TRUE(b.Build()) << b.error();
- spirv::Builder& b = Build();
-
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
-
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 13u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
-%4 = OpTypeVector %5 3
-%6 = OpTypeInt 32 0
-%7 = OpConstant %6 4
-%3 = OpTypeArray %4 %7
-%2 = OpTypePointer Function %3
-%8 = OpConstantNull %3
-%9 = OpTypeInt 32 1
-%10 = OpConstant %9 3
-%11 = OpConstant %9 2
-%12 = OpTypePointer Function %5
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeInt 32 1
+%6 = OpConstant %5 2
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %8
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%13 = OpAccessChain %12 %1 %10 %11
+ R"(OpStore %7 %6
+OpReturn
)");
+
+ Validate(b);
}
-TEST_F(BuilderTest, IndexAccessor_ArrayRef_ArrayWithSwizzle) {
- auto* ary4 = ty.array(ty.vec3<f32>(), 4_u);
+TEST_F(BuilderTest, Runtime_IndexAccessor_Vector) {
+ // var ary : vec3<u32>;
+ // var x = ary[1i];
- // var a : array<vec3<f32>, 4u>;
- // a[2i].xy;
+ auto* ary = Var("ary", ty.vec3<u32>());
+ auto* x = Var("x", nullptr, IndexAccessor(ary, 1_i));
+ WrapInFunction(ary, x);
- auto* var = Var("ary", ary4);
+ spirv::Builder& b = SanitizeAndBuild();
- auto* expr = MemberAccessor(IndexAccessor("ary", 2_i), "xy");
- WrapInFunction(var, expr);
+ ASSERT_TRUE(b.Build()) << b.error();
- spirv::Builder& b = Build();
-
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 15u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
-%4 = OpTypeVector %5 3
-%6 = OpTypeInt 32 0
-%7 = OpConstant %6 4
-%3 = OpTypeArray %4 %7
-%2 = OpTypePointer Function %3
-%8 = OpConstantNull %3
-%9 = OpTypeInt 32 1
-%10 = OpConstant %9 2
-%11 = OpTypePointer Function %4
-%13 = OpTypeVector %5 2
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%8 = OpTypeInt 32 0
+%7 = OpTypeVector %8 3
+%6 = OpTypePointer Function %7
+%9 = OpConstantNull %7
+%10 = OpTypeInt 32 1
+%11 = OpConstant %10 1
+%12 = OpTypePointer Function %8
+%16 = OpConstantNull %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %8
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+%15 = OpVariable %12 Function %16
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+%14 = OpLoad %8 %13
+OpStore %15 %14
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Dynamic_IndexAccessor_Vector) {
+ // var ary : vec3<f32>;
+ // var idx : i32;
+ // var x = ary[idx];
+
+ auto* ary = Var("ary", ty.vec3<f32>());
+ auto* idx = Var("idx", ty.i32());
+ auto* x = Var("x", nullptr, IndexAccessor(ary, idx));
+ WrapInFunction(ary, idx, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%8 = OpTypeFloat 32
+%7 = OpTypeVector %8 3
+%6 = OpTypePointer Function %7
+%9 = OpConstantNull %7
+%12 = OpTypeInt 32 1
+%11 = OpTypePointer Function %12
+%13 = OpConstantNull %12
+%15 = OpTypePointer Function %8
+%19 = OpConstantNull %8
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+%10 = OpVariable %11 Function %13
+%18 = OpVariable %15 Function %19
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%14 = OpLoad %12 %10
+%16 = OpAccessChain %15 %5 %14
+%17 = OpLoad %8 %16
+OpStore %18 %17
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Const_IndexAccessor_Vector2) {
+ // let ary : vec3<i32>(1, 2, 3);
+ // var x = ary[1i + 2i];
+
+ auto* ary = Let("ary", nullptr, vec3<i32>(1_i, 2_i, 3_i));
+ auto* x = Var("x", nullptr, IndexAccessor(ary, Add(1_i, 2_i)));
+ WrapInFunction(ary, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeInt 32 1
+%5 = OpTypeVector %6 3
+%7 = OpConstant %6 1
+%8 = OpConstant %6 2
+%9 = OpConstant %6 3
+%10 = OpConstantComposite %5 %7 %8 %9
+%14 = OpTypePointer Function %6
+%15 = OpConstantNull %6
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%13 = OpVariable %14 Function %15
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%11 = OpIAdd %6 %7 %8
+%12 = OpVectorExtractDynamic %6 %10 %11
+OpStore %13 %12
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Runtime_IndexAccessor_Vector2) {
+ // var ary : vec3<f32>;
+ // var x = ary[1i + 2i];
+
+ auto* ary = Var("ary", ty.vec3<f32>());
+ auto* x = Var("x", nullptr, IndexAccessor(ary, Add(1_i, 2_i)));
+ WrapInFunction(ary, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%8 = OpTypeFloat 32
+%7 = OpTypeVector %8 3
+%6 = OpTypePointer Function %7
+%9 = OpConstantNull %7
+%10 = OpTypeInt 32 1
+%11 = OpConstant %10 1
+%12 = OpConstant %10 2
+%14 = OpTypePointer Function %8
+%18 = OpConstantNull %8
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+%17 = OpVariable %14 Function %18
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpIAdd %10 %11 %12
+%15 = OpAccessChain %14 %5 %13
+%16 = OpLoad %8 %15
+OpStore %17 %16
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Dynamic_IndexAccessor_Vector2) {
+ // var ary : vec3<f32>;
+ // var one = 1i;
+ // var x = ary[one + 2i];
+
+ auto* ary = Var("ary", ty.vec3<f32>());
+ auto* one = Var("one", nullptr, Expr(1_i));
+ auto* x = Var("x", nullptr, IndexAccessor(ary, Add(one, 2_i)));
+ WrapInFunction(ary, one, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%8 = OpTypeFloat 32
+%7 = OpTypeVector %8 3
+%6 = OpTypePointer Function %7
+%9 = OpConstantNull %7
+%10 = OpTypeInt 32 1
+%11 = OpConstant %10 1
+%13 = OpTypePointer Function %10
+%14 = OpConstantNull %10
+%16 = OpConstant %10 2
+%18 = OpTypePointer Function %8
+%22 = OpConstantNull %8
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+%12 = OpVariable %13 Function %14
+%21 = OpVariable %18 Function %22
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %12 %11
+%15 = OpLoad %10 %12
+%17 = OpIAdd %10 %15 %16
+%19 = OpAccessChain %18 %5 %17
+%20 = OpLoad %8 %19
+OpStore %21 %20
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Let_IndexAccessor_Array_MultiLevel) {
+ // let ary = array<vec3<f32>, 2u>(vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(4.0f, 5.0f, 6.0f));
+ // var x = ary[1i][2i];
+
+ auto* ary =
+ Let("ary", nullptr,
+ array(ty.vec3<f32>(), 2_u, vec3<f32>(1._f, 2._f, 3._f), vec3<f32>(4._f, 5._f, 6._f)));
+ auto* x = Var("x", nullptr, IndexAccessor(IndexAccessor(ary, 1_i), 2_i));
+ WrapInFunction(ary, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%7 = OpTypeFloat 32
+%6 = OpTypeVector %7 3
+%8 = OpTypeInt 32 0
+%9 = OpConstant %8 2
+%5 = OpTypeArray %6 %9
+%10 = OpConstant %7 1
+%11 = OpConstant %7 2
+%12 = OpConstant %7 3
+%13 = OpConstantComposite %6 %10 %11 %12
+%14 = OpConstant %7 4
+%15 = OpConstant %7 5
+%16 = OpConstant %7 6
+%17 = OpConstantComposite %6 %14 %15 %16
+%18 = OpConstantComposite %5 %13 %17
+%19 = OpTypeInt 32 1
+%20 = OpConstant %19 1
+%22 = OpConstant %19 2
+%25 = OpTypePointer Function %7
+%26 = OpConstantNull %7
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%24 = OpVariable %25 Function %26
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%12 = OpAccessChain %11 %1 %10
-%14 = OpLoad %4 %12
-%15 = OpVectorShuffle %13 %14 %14 0 1
+ R"(%21 = OpCompositeExtract %6 %18 1
+%23 = OpCompositeExtract %7 %21 2
+OpStore %24 %23
+OpReturn
)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Const_IndexAccessor_Array_MultiLevel) {
+ // const ary = array<vec3<f32>, 2u>(vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(4.0f, 5.0f, 6.0f));
+ // var x = ary[1i][2i];
+
+ auto* ary =
+ Const("ary", nullptr,
+ array(ty.vec3<f32>(), 2_u, vec3<f32>(1._f, 2._f, 3._f), vec3<f32>(4._f, 5._f, 6._f)));
+ auto* x = Var("x", nullptr, IndexAccessor(IndexAccessor(ary, 1_i), 2_i));
+ WrapInFunction(ary, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 32
+%6 = OpConstant %5 6
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(OpStore %7 %6
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Runtime_IndexAccessor_Array_MultiLevel) {
+ // var ary : array<vec3<f32>, 4u>;
+ // var x = ary[1i][2i];
+
+ auto* ary = Var("ary", ty.array(ty.vec3<f32>(), 4_u));
+ auto* x = Var("x", nullptr, IndexAccessor(IndexAccessor(ary, 1_i), 2_i));
+ WrapInFunction(ary, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeVector %9 3
+%10 = OpTypeInt 32 0
+%11 = OpConstant %10 4
+%7 = OpTypeArray %8 %11
+%6 = OpTypePointer Function %7
+%12 = OpConstantNull %7
+%13 = OpTypeInt 32 1
+%14 = OpConstant %13 1
+%15 = OpConstant %13 2
+%16 = OpTypePointer Function %9
+%20 = OpConstantNull %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+%19 = OpVariable %16 Function %20
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%17 = OpAccessChain %16 %5 %14 %15
+%18 = OpLoad %9 %17
+OpStore %19 %18
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Dynamic_IndexAccessor_Array_MultiLevel) {
+ // var ary : array<vec3<f32>, 4u>;
+ // var one = 1i;
+ // var x = ary[one][2i];
+
+ auto* ary = Var("ary", ty.array(ty.vec3<f32>(), 4_u));
+ auto* one = Var("one", nullptr, Expr(3_i));
+ auto* x = Var("x", nullptr, IndexAccessor(IndexAccessor(ary, one), 2_i));
+ WrapInFunction(ary, one, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeVector %9 3
+%10 = OpTypeInt 32 0
+%11 = OpConstant %10 4
+%7 = OpTypeArray %8 %11
+%6 = OpTypePointer Function %7
+%12 = OpConstantNull %7
+%13 = OpTypeInt 32 1
+%14 = OpConstant %13 3
+%16 = OpTypePointer Function %13
+%17 = OpConstantNull %13
+%19 = OpConstant %13 2
+%20 = OpTypePointer Function %9
+%24 = OpConstantNull %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+%15 = OpVariable %16 Function %17
+%23 = OpVariable %20 Function %24
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %15 %14
+%18 = OpLoad %13 %15
+%21 = OpAccessChain %20 %5 %18 %19
+%22 = OpLoad %9 %21
+OpStore %23 %22
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Const_IndexAccessor_Array_ArrayWithSwizzle) {
+ // let ary = array<vec3<f32>, 2u>(vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(4.0f, 5.0f, 6.0f));
+ // var x = a[1i].xy;
+
+ auto* ary =
+ Let("ary", nullptr,
+ array(ty.vec3<f32>(), 2_u, vec3<f32>(1._f, 2._f, 3._f), vec3<f32>(4._f, 5._f, 6._f)));
+ auto* x = Var("x", nullptr, MemberAccessor(IndexAccessor("ary", 1_i), "xy"));
+ WrapInFunction(ary, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%7 = OpTypeFloat 32
+%6 = OpTypeVector %7 3
+%8 = OpTypeInt 32 0
+%9 = OpConstant %8 2
+%5 = OpTypeArray %6 %9
+%10 = OpConstant %7 1
+%11 = OpConstant %7 2
+%12 = OpConstant %7 3
+%13 = OpConstantComposite %6 %10 %11 %12
+%14 = OpConstant %7 4
+%15 = OpConstant %7 5
+%16 = OpConstant %7 6
+%17 = OpConstantComposite %6 %14 %15 %16
+%18 = OpConstantComposite %5 %13 %17
+%19 = OpTypeInt 32 1
+%20 = OpConstant %19 1
+%22 = OpTypeVector %7 2
+%25 = OpTypePointer Function %22
+%26 = OpConstantNull %22
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%24 = OpVariable %25 Function %26
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%21 = OpCompositeExtract %6 %18 1
+%23 = OpVectorShuffle %22 %21 %21 0 1
+OpStore %24 %23
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Runtime_IndexAccessor_Array_ArrayWithSwizzle) {
+ // var ary : array<vec3<f32>, 4u>;
+ // var x = ary[1i].xy;
+
+ auto* ary = Var("ary", ty.array(ty.vec3<f32>(), 4_u));
+ auto* x = Var("x", nullptr, MemberAccessor(IndexAccessor("ary", 1_i), "xy"));
+ WrapInFunction(ary, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeVector %9 3
+%10 = OpTypeInt 32 0
+%11 = OpConstant %10 4
+%7 = OpTypeArray %8 %11
+%6 = OpTypePointer Function %7
+%12 = OpConstantNull %7
+%13 = OpTypeInt 32 1
+%14 = OpConstant %13 1
+%15 = OpTypePointer Function %8
+%17 = OpTypeVector %9 2
+%21 = OpTypePointer Function %17
+%22 = OpConstantNull %17
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+%20 = OpVariable %21 Function %22
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%16 = OpAccessChain %15 %5 %14
+%18 = OpLoad %8 %16
+%19 = OpVectorShuffle %17 %18 %18 0 1
+OpStore %20 %19
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Dynamic_IndexAccessor_Array_ArrayWithSwizzle) {
+ // var ary : array<vec3<f32>, 4u>;
+ // var one = 1i;
+ // var x = ary[one].xy;
+
+ auto* ary = Var("ary", ty.array(ty.vec3<f32>(), 4_u));
+ auto* one = Var("one", nullptr, Expr(1_i));
+ auto* x = Var("x", nullptr, MemberAccessor(IndexAccessor("ary", one), "xy"));
+ WrapInFunction(ary, one, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeVector %9 3
+%10 = OpTypeInt 32 0
+%11 = OpConstant %10 4
+%7 = OpTypeArray %8 %11
+%6 = OpTypePointer Function %7
+%12 = OpConstantNull %7
+%13 = OpTypeInt 32 1
+%14 = OpConstant %13 1
+%16 = OpTypePointer Function %13
+%17 = OpConstantNull %13
+%19 = OpTypePointer Function %8
+%21 = OpTypeVector %9 2
+%25 = OpTypePointer Function %21
+%26 = OpConstantNull %21
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+%15 = OpVariable %16 Function %17
+%24 = OpVariable %25 Function %26
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %15 %14
+%18 = OpLoad %13 %15
+%20 = OpAccessChain %19 %5 %18
+%22 = OpLoad %8 %20
+%23 = OpVectorShuffle %21 %22 %22 0 1
+OpStore %24 %23
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Let_IndexAccessor_Nested_Array_f32) {
+ // let pos : array<array<f32, 2>, 3u> = array<vec2<f32, 2>, 3u>(
+ // array<f32, 2>(0.0, 0.5),
+ // array<f32, 2>(-0.5, -0.5),
+ // array<f32, 2>(0.5, -0.5));
+ // var x = pos[1u][0u];
+
+ auto* pos = Let("pos", ty.array(ty.vec2<f32>(), 3_u),
+ Construct(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0_f, 0.5_f),
+ vec2<f32>(-0.5_f, -0.5_f), vec2<f32>(0.5_f, -0.5_f)));
+ auto* x = Var("x", nullptr, IndexAccessor(IndexAccessor(pos, 1_u), 0_u));
+ WrapInFunction(pos, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%7 = OpTypeFloat 32
+%6 = OpTypeVector %7 2
+%8 = OpTypeInt 32 0
+%9 = OpConstant %8 3
+%5 = OpTypeArray %6 %9
+%10 = OpConstantNull %7
+%11 = OpConstant %7 0.5
+%12 = OpConstantComposite %6 %10 %11
+%13 = OpConstant %7 -0.5
+%14 = OpConstantComposite %6 %13 %13
+%15 = OpConstantComposite %6 %11 %13
+%16 = OpConstantComposite %5 %12 %14 %15
+%17 = OpConstant %8 1
+%19 = OpConstantNull %8
+%22 = OpTypePointer Function %7
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%21 = OpVariable %22 Function %10
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%18 = OpCompositeExtract %6 %16 1
+%20 = OpCompositeExtract %7 %18 0
+OpStore %21 %20
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Const_IndexAccessor_Nested_Array_f32) {
+ // const pos : array<array<f32, 2>, 3u> = array<vec2<f32, 2>, 3u>(
+ // array<f32, 2>(0.0, 0.5),
+ // array<f32, 2>(-0.5, -0.5),
+ // array<f32, 2>(0.5, -0.5));
+ // var x = pos[1u][0u];
+
+ auto* pos = Const("pos", ty.array(ty.vec2<f32>(), 3_u),
+ Construct(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0_f, 0.5_f),
+ vec2<f32>(-0.5_f, -0.5_f), vec2<f32>(0.5_f, -0.5_f)));
+ auto* x = Var("x", nullptr, IndexAccessor(IndexAccessor(pos, 1_u), 0_u));
+ WrapInFunction(pos, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 32
+%6 = OpConstant %5 -0.5
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(OpStore %7 %6
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Runtime_IndexAccessor_Nested_Array_f32) {
+ // var pos : array<array<f32, 2>, 3u>;
+ // var x = pos[1u][2u];
+
+ auto* pos = Var("pos", ty.array(ty.vec2<f32>(), 3_u));
+ auto* x = Var("x", nullptr, IndexAccessor(IndexAccessor(pos, 1_u), 2_u));
+ WrapInFunction(pos, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeVector %9 2
+%10 = OpTypeInt 32 0
+%11 = OpConstant %10 3
+%7 = OpTypeArray %8 %11
+%6 = OpTypePointer Function %7
+%12 = OpConstantNull %7
+%13 = OpConstant %10 1
+%14 = OpConstant %10 2
+%15 = OpTypePointer Function %9
+%19 = OpConstantNull %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+%18 = OpVariable %15 Function %19
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%16 = OpAccessChain %15 %5 %13 %14
+%17 = OpLoad %9 %16
+OpStore %18 %17
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Dynamic_IndexAccessor_Nested_Array_f32) {
+ // var pos : array<array<f32, 2>, 3u>;
+ // var one = 1u;
+ // var x = pos[one][2u];
+
+ auto* pos = Var("pos", ty.array(ty.vec2<f32>(), 3_u));
+ auto* one = Var("one", nullptr, Expr(2_u));
+ auto* x = Var("x", nullptr, IndexAccessor(IndexAccessor(pos, "one"), 2_u));
+ WrapInFunction(pos, one, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeVector %9 2
+%10 = OpTypeInt 32 0
+%11 = OpConstant %10 3
+%7 = OpTypeArray %8 %11
+%6 = OpTypePointer Function %7
+%12 = OpConstantNull %7
+%13 = OpConstant %10 2
+%15 = OpTypePointer Function %10
+%16 = OpConstantNull %10
+%18 = OpTypePointer Function %9
+%22 = OpConstantNull %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+%14 = OpVariable %15 Function %16
+%21 = OpVariable %18 Function %22
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %14 %13
+%17 = OpLoad %10 %14
+%19 = OpAccessChain %18 %5 %17 %13
+%20 = OpLoad %9 %19
+OpStore %21 %20
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Let_IndexAccessor_Matrix) {
+ // let a : mat2x2<f32>(vec2<f32>(1., 2.), vec2<f32>(3., 4.));
+ // var x = a[1i]
+
+ auto* a = Let("a", ty.mat2x2<f32>(),
+ Construct(ty.mat2x2<f32>(), Construct(ty.vec2<f32>(), 1_f, 2_f),
+ Construct(ty.vec2<f32>(), 3_f, 4_f)));
+ auto* x = Var("x", nullptr, IndexAccessor("a", 1_i));
+ WrapInFunction(a, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%7 = OpTypeFloat 32
+%6 = OpTypeVector %7 2
+%5 = OpTypeMatrix %6 2
+%8 = OpConstant %7 1
+%9 = OpConstant %7 2
+%10 = OpConstantComposite %6 %8 %9
+%11 = OpConstant %7 3
+%12 = OpConstant %7 4
+%13 = OpConstantComposite %6 %11 %12
+%14 = OpConstantComposite %5 %10 %13
+%15 = OpTypeInt 32 1
+%16 = OpConstant %15 1
+%19 = OpTypePointer Function %6
+%20 = OpConstantNull %6
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%18 = OpVariable %19 Function %20
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%17 = OpCompositeExtract %6 %14 1
+OpStore %18 %17
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Const_IndexAccessor_Matrix) {
+ // const a : mat2x2<f32>(vec2<f32>(1., 2.), vec2<f32>(3., 4.));
+ // var x = a[1i]
+
+ auto* a = Const("a", ty.mat2x2<f32>(),
+ Construct(ty.mat2x2<f32>(), Construct(ty.vec2<f32>(), 1_f, 2_f),
+ Construct(ty.vec2<f32>(), 3_f, 4_f)));
+ auto* x = Var("x", nullptr, IndexAccessor("a", 1_i));
+ WrapInFunction(a, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 3
+%8 = OpConstant %6 4
+%9 = OpConstantComposite %5 %7 %8
+%11 = OpTypePointer Function %5
+%12 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%10 = OpVariable %11 Function %12
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(OpStore %10 %9
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Runtime_IndexAccessor_Matrix) {
+ // var a : mat2x2<f32>;
+ // var x = a[1i]
+
+ auto* a = Var("a", ty.mat2x2<f32>());
+ auto* x = Var("x", nullptr, IndexAccessor("a", 1_i));
+ WrapInFunction(a, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeVector %9 2
+%7 = OpTypeMatrix %8 2
+%6 = OpTypePointer Function %7
+%10 = OpConstantNull %7
+%11 = OpTypeInt 32 1
+%12 = OpConstant %11 1
+%13 = OpTypePointer Function %8
+%17 = OpConstantNull %8
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+%16 = OpVariable %13 Function %17
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%14 = OpAccessChain %13 %5 %12
+%15 = OpLoad %8 %14
+OpStore %16 %15
+OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, Dynamic_IndexAccessor_Matrix) {
+ // var a : mat2x2<f32>;
+ // var idx : i32
+ // var x = a[idx]
+
+ auto* a = Var("a", ty.mat2x2<f32>());
+ auto* idx = Var("idx", ty.i32());
+ auto* x = Var("x", nullptr, IndexAccessor("a", idx));
+ WrapInFunction(a, idx, x);
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeVector %9 2
+%7 = OpTypeMatrix %8 2
+%6 = OpTypePointer Function %7
+%10 = OpConstantNull %7
+%13 = OpTypeInt 32 1
+%12 = OpTypePointer Function %13
+%14 = OpConstantNull %13
+%16 = OpTypePointer Function %8
+%20 = OpConstantNull %8
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+%11 = OpVariable %12 Function %14
+%19 = OpVariable %16 Function %20
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%15 = OpLoad %13 %11
+%17 = OpAccessChain %16 %5 %15
+%18 = OpLoad %8 %17
+OpStore %19 %18
+OpReturn
+)");
+
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor) {
@@ -229,27 +910,28 @@
auto* expr = MemberAccessor("ident", "b");
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 9u);
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%8 = OpTypeFloat 32
+%7 = OpTypeStruct %8 %8
+%6 = OpTypePointer Function %7
+%9 = OpConstantNull %7
+%10 = OpTypeInt 32 0
+%11 = OpConstant %10 1
+%12 = OpTypePointer Function %8
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+%14 = OpLoad %8 %13
+OpReturn
+)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeStruct %4 %4
-%2 = OpTypePointer Function %3
-%5 = OpConstantNull %3
-%6 = OpTypeInt 32 0
-%7 = OpConstant %6 1
-%8 = OpTypePointer Function %4
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %5
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%9 = OpAccessChain %8 %1 %7
-)");
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_Nested) {
@@ -274,29 +956,31 @@
auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "b");
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 11u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
-%4 = OpTypeStruct %5 %5
-%3 = OpTypeStruct %4
-%2 = OpTypePointer Function %3
-%6 = OpConstantNull %3
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%9 = OpConstant %7 1
-%10 = OpTypePointer Function %5
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeStruct %9 %9
+%7 = OpTypeStruct %8
+%6 = OpTypePointer Function %7
+%10 = OpConstantNull %7
+%11 = OpTypeInt 32 0
+%12 = OpConstant %11 0
+%13 = OpConstant %11 1
+%14 = OpTypePointer Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %6
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%11 = OpAccessChain %10 %1 %8 %9
+ R"(%15 = OpAccessChain %14 %5 %12 %13
+%16 = OpLoad %9 %15
+OpReturn
)");
+
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_NonPointer) {
@@ -317,21 +1001,23 @@
auto* expr = MemberAccessor("ident", "b");
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 5u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
-%1 = OpTypeStruct %2 %2
-%3 = OpConstantNull %2
-%4 = OpConstantComposite %1 %3 %3
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeStruct %6 %6
+%7 = OpConstantNull %6
+%8 = OpConstantComposite %5 %7 %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%5 = OpCompositeExtract %2 %4 1
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%9 = OpCompositeExtract %6 %8 1
+OpReturn
)");
+
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_Nested_NonPointer) {
@@ -357,24 +1043,27 @@
auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "b");
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 8u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
-%2 = OpTypeStruct %3 %3
-%1 = OpTypeStruct %2
-%4 = OpConstantNull %3
-%5 = OpConstantComposite %2 %4 %4
-%6 = OpConstantComposite %1 %5
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%7 = OpTypeFloat 32
+%6 = OpTypeStruct %7 %7
+%5 = OpTypeStruct %6
+%8 = OpConstantNull %7
+%9 = OpConstantComposite %6 %8 %8
+%10 = OpConstantComposite %5 %9
)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%7 = OpCompositeExtract %2 %6 0
-%8 = OpCompositeExtract %3 %7 1
+ R"(%11 = OpCompositeExtract %6 %10 0
+%12 = OpCompositeExtract %7 %11 1
+OpReturn
)");
+
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
@@ -401,28 +1090,30 @@
auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "a");
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 10u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
-%4 = OpTypeStruct %5 %5
-%3 = OpTypeStruct %4
-%2 = OpTypePointer Function %3
-%6 = OpConstantNull %3
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%9 = OpTypePointer Function %5
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeStruct %9 %9
+%7 = OpTypeStruct %8
+%6 = OpTypePointer Function %7
+%10 = OpConstantNull %7
+%11 = OpTypeInt 32 0
+%12 = OpConstant %11 0
+%13 = OpTypePointer Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %6
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%10 = OpAccessChain %9 %1 %8 %8
+ R"(%14 = OpAccessChain %13 %5 %12 %12
+%15 = OpLoad %9 %14
+OpReturn
)");
+
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) {
@@ -446,30 +1137,31 @@
auto* expr = Assign(MemberAccessor(MemberAccessor("ident", "inner"), "a"), Expr(2_f));
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_TRUE(b.GenerateAssignStatement(expr)) << b.error();
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
-%4 = OpTypeStruct %5 %5
-%3 = OpTypeStruct %4
-%2 = OpTypePointer Function %3
-%6 = OpConstantNull %3
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%9 = OpTypePointer Function %5
-%11 = OpConstant %5 2
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeStruct %9 %9
+%7 = OpTypeStruct %8
+%6 = OpTypePointer Function %7
+%10 = OpConstantNull %7
+%11 = OpTypeInt 32 0
+%12 = OpConstant %11 0
+%13 = OpTypePointer Function %9
+%15 = OpConstant %9 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %6
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%10 = OpAccessChain %9 %1 %8 %8
-OpStore %10 %11
+ R"(%14 = OpAccessChain %13 %5 %12 %12
+OpStore %14 %15
+OpReturn
)");
+
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) {
@@ -497,33 +1189,33 @@
auto* expr = Assign("store", rhs);
WrapInFunction(var, store, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(store)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_TRUE(b.GenerateAssignStatement(expr)) << b.error();
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
-%4 = OpTypeStruct %5 %5
-%3 = OpTypeStruct %4
-%2 = OpTypePointer Function %3
-%6 = OpConstantNull %3
-%8 = OpTypePointer Function %5
-%9 = OpConstantNull %5
-%10 = OpTypeInt 32 0
-%11 = OpConstant %10 0
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%9 = OpTypeFloat 32
+%8 = OpTypeStruct %9 %9
+%7 = OpTypeStruct %8
+%6 = OpTypePointer Function %7
+%10 = OpConstantNull %7
+%12 = OpTypePointer Function %9
+%13 = OpConstantNull %9
+%14 = OpTypeInt 32 0
+%15 = OpConstant %14 0
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %6
-%7 = OpVariable %8 Function %9
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+%11 = OpVariable %12 Function %13
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%12 = OpAccessChain %8 %1 %11 %11
-%13 = OpLoad %5 %12
-OpStore %7 %13
+ R"(%16 = OpAccessChain %12 %5 %15 %15
+%17 = OpLoad %9 %16
+OpStore %11 %17
+OpReturn
)");
+
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_Swizzle_Single) {
@@ -534,27 +1226,28 @@
auto* expr = MemberAccessor("ident", "y");
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 9u);
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%8 = OpTypeFloat 32
+%7 = OpTypeVector %8 3
+%6 = OpTypePointer Function %7
+%9 = OpConstantNull %7
+%10 = OpTypeInt 32 0
+%11 = OpConstant %10 1
+%12 = OpTypePointer Function %8
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+%14 = OpLoad %8 %13
+OpReturn
+)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Function %3
-%5 = OpConstantNull %3
-%6 = OpTypeInt 32 0
-%7 = OpConstant %6 1
-%8 = OpTypePointer Function %4
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %5
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%9 = OpAccessChain %8 %1 %7
-)");
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_Swizzle_MultipleNames) {
@@ -565,26 +1258,26 @@
auto* expr = MemberAccessor("ident", "yx");
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 8u);
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%8 = OpTypeFloat 32
+%7 = OpTypeVector %8 3
+%6 = OpTypePointer Function %7
+%9 = OpConstantNull %7
+%10 = OpTypeVector %8 2
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%11 = OpLoad %7 %5
+%12 = OpVectorShuffle %10 %11 %11 1 0
+OpReturn
+)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Function %3
-%5 = OpConstantNull %3
-%6 = OpTypeVector %4 2
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %5
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%7 = OpLoad %3 %1
-%8 = OpVectorShuffle %6 %7 %7 1 0
-)");
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_Swizzle_of_Swizzle) {
@@ -595,27 +1288,27 @@
auto* expr = MemberAccessor(MemberAccessor("ident", "yxz"), "xz");
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 9u);
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%8 = OpTypeFloat 32
+%7 = OpTypeVector %8 3
+%6 = OpTypePointer Function %7
+%9 = OpConstantNull %7
+%12 = OpTypeVector %8 2
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+%11 = OpVectorShuffle %7 %10 %10 1 0 2
+%13 = OpVectorShuffle %12 %11 %11 0 2
+OpReturn
+)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Function %3
-%5 = OpConstantNull %3
-%8 = OpTypeVector %4 2
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %5
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%6 = OpLoad %3 %1
-%7 = OpVectorShuffle %3 %6 %6 1 0 2
-%9 = OpVectorShuffle %8 %7 %7 0 2
-)");
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_Member_of_Swizzle) {
@@ -626,26 +1319,26 @@
auto* expr = MemberAccessor(MemberAccessor("ident", "yxz"), "x");
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 8u);
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%8 = OpTypeFloat 32
+%7 = OpTypeVector %8 3
+%6 = OpTypePointer Function %7
+%9 = OpConstantNull %7
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+%11 = OpVectorShuffle %7 %10 %10 1 0 2
+%12 = OpCompositeExtract %8 %11 0
+OpReturn
+)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Function %3
-%5 = OpConstantNull %3
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %5
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%6 = OpLoad %3 %1
-%7 = OpVectorShuffle %3 %6 %6 1 0 2
-%8 = OpCompositeExtract %4 %7 0
-)");
+ Validate(b);
}
TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) {
@@ -656,28 +1349,28 @@
auto* expr = IndexAccessor(MemberAccessor("ident", "yxz"), 1_i);
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 10u);
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%8 = OpTypeFloat 32
+%7 = OpTypeVector %8 3
+%6 = OpTypePointer Function %7
+%9 = OpConstantNull %7
+%12 = OpTypeInt 32 1
+%13 = OpConstant %12 1
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+%11 = OpVectorShuffle %7 %10 %10 1 0 2
+%14 = OpCompositeExtract %8 %11 1
+OpReturn
+)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
-%3 = OpTypeVector %4 3
-%2 = OpTypePointer Function %3
-%5 = OpConstantNull %3
-%8 = OpTypeInt 32 1
-%9 = OpConstant %8 1
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %5
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%6 = OpLoad %3 %1
-%7 = OpVectorShuffle %3 %6 %6 1 0 2
-%10 = OpCompositeExtract %4 %7 1
-)");
+ Validate(b);
}
TEST_F(BuilderTest, IndexAccessor_Mixed_ArrayAndMember) {
@@ -709,323 +1402,37 @@
"yx");
WrapInFunction(var, expr);
- spirv::Builder& b = Build();
-
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
-
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 22u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%9 = OpTypeFloat 32
-%8 = OpTypeVector %9 3
-%7 = OpTypeStruct %8
-%6 = OpTypeStruct %7
-%10 = OpTypeInt 32 0
-%11 = OpConstant %10 3
-%5 = OpTypeArray %6 %11
-%4 = OpTypeStruct %5
-%12 = OpConstant %10 2
-%3 = OpTypeArray %4 %12
-%2 = OpTypePointer Function %3
-%13 = OpConstantNull %3
-%14 = OpTypeInt 32 1
-%15 = OpConstantNull %14
-%16 = OpConstant %10 0
-%17 = OpConstant %14 2
-%18 = OpTypePointer Function %8
-%20 = OpTypeVector %9 2
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%1 = OpVariable %2 Function %13
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%19 = OpAccessChain %18 %1 %15 %16 %17 %16 %16
-%21 = OpLoad %8 %19
-%22 = OpVectorShuffle %20 %21 %21 1 0
-)");
-}
-
-TEST_F(BuilderTest, IndexAccessor_Of_Vec) {
- // let pos : array<vec2<f32>, 3u> = array<vec2<f32>, 3u>(
- // vec2<f32>(0.0, 0.5),
- // vec2<f32>(-0.5, -0.5),
- // vec2<f32>(0.5, -0.5));
- // pos[1u]
-
- auto* var = Let("pos", ty.array(ty.vec2<f32>(), 3_u),
- Construct(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0_f, 0.5_f),
- vec2<f32>(-0.5_f, -0.5_f), vec2<f32>(0.5_f, -0.5_f)));
-
- auto* expr = IndexAccessor("pos", 1_u);
- WrapInFunction(var, expr);
-
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build());
+ ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
-%7 = OpTypeFloat 32
-%6 = OpTypeVector %7 2
-%8 = OpTypeInt 32 0
-%9 = OpConstant %8 3
-%5 = OpTypeArray %6 %9
-%10 = OpConstant %7 0
-%11 = OpConstant %7 0.5
-%12 = OpConstantComposite %6 %10 %11
-%13 = OpConstant %7 -0.5
-%14 = OpConstantComposite %6 %13 %13
-%15 = OpConstantComposite %6 %11 %13
-%16 = OpConstantComposite %5 %12 %14 %15
-%17 = OpConstant %8 1
+%13 = OpTypeFloat 32
+%12 = OpTypeVector %13 3
+%11 = OpTypeStruct %12
+%10 = OpTypeStruct %11
+%14 = OpTypeInt 32 0
+%15 = OpConstant %14 3
+%9 = OpTypeArray %10 %15
+%8 = OpTypeStruct %9
+%16 = OpConstant %14 2
+%7 = OpTypeArray %8 %16
+%6 = OpTypePointer Function %7
+%17 = OpConstantNull %7
+%18 = OpTypeInt 32 1
+%19 = OpConstantNull %18
+%20 = OpConstant %14 0
+%21 = OpConstant %18 2
+%22 = OpTypePointer Function %12
+%24 = OpTypeVector %13 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%18 = OpCompositeExtract %6 %16 1
-OpReturn
-)");
-
- Validate(b);
-}
-
-TEST_F(BuilderTest, IndexAccessor_Of_Array_Of_f32) {
- // let pos : array<array<f32, 2>, 3u> = array<vec2<f32, 2>, 3u>(
- // array<f32, 2>(0.0, 0.5),
- // array<f32, 2>(-0.5, -0.5),
- // array<f32, 2>(0.5, -0.5));
- // pos[2u][1u]
-
- auto* var = Let("pos", ty.array(ty.vec2<f32>(), 3_u),
- Construct(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0_f, 0.5_f),
- vec2<f32>(-0.5_f, -0.5_f), vec2<f32>(0.5_f, -0.5_f)));
-
- auto* expr = IndexAccessor(IndexAccessor("pos", 2_u), 1_u);
- WrapInFunction(var, expr);
-
- spirv::Builder& b = SanitizeAndBuild();
-
- ASSERT_TRUE(b.Build());
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = OpTypeFloat 32
-%6 = OpTypeVector %7 2
-%8 = OpTypeInt 32 0
-%9 = OpConstant %8 3
-%5 = OpTypeArray %6 %9
-%10 = OpConstant %7 0
-%11 = OpConstant %7 0.5
-%12 = OpConstantComposite %6 %10 %11
-%13 = OpConstant %7 -0.5
-%14 = OpConstantComposite %6 %13 %13
-%15 = OpConstantComposite %6 %11 %13
-%16 = OpConstantComposite %5 %12 %14 %15
-%17 = OpConstant %8 2
-%19 = OpConstant %8 1
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%18 = OpCompositeExtract %6 %16 2
-%20 = OpCompositeExtract %7 %18 1
-OpReturn
-)");
-
- Validate(b);
-}
-
-TEST_F(BuilderTest, IndexAccessor_Vec_Literal) {
- // let pos : vec2<f32> = vec2<f32>(0.0, 0.5);
- // pos[1]
-
- auto* var = Let("pos", ty.vec2<f32>(), vec2<f32>(0_f, 0.5_f));
-
- auto* expr = IndexAccessor("pos", 1_u);
- WrapInFunction(var, expr);
-
- spirv::Builder& b = Build();
-
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 8u) << b.error();
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
-%1 = OpTypeVector %2 2
-%3 = OpConstant %2 0
-%4 = OpConstant %2 0.5
-%5 = OpConstantComposite %1 %3 %4
-%6 = OpTypeInt 32 0
-%7 = OpConstant %6 1
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), "");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%8 = OpCompositeExtract %2 %5 1
-)");
-}
-
-TEST_F(BuilderTest, IndexAccessor_Vec_Dynamic) {
- // let pos : vec2<f32> = vec2<f32>(0.0, 0.5);
- // idx : i32
- // pos[idx]
-
- auto* var = Let("pos", ty.vec2<f32>(), vec2<f32>(0_f, 0.5_f));
- auto* idx = Var("idx", ty.i32());
- auto* expr = IndexAccessor("pos", idx);
-
- WrapInFunction(var, idx, expr);
-
- spirv::Builder& b = Build();
-
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(idx)) << b.error();
- EXPECT_EQ(b.GenerateAccessorExpression(expr), 11u) << b.error();
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
-%1 = OpTypeVector %2 2
-%3 = OpConstant %2 0
-%4 = OpConstant %2 0.5
-%5 = OpConstantComposite %1 %3 %4
-%8 = OpTypeInt 32 1
-%7 = OpTypePointer Function %8
-%9 = OpConstantNull %8
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%6 = OpVariable %7 Function %9
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %17
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%10 = OpLoad %8 %6
-%11 = OpVectorExtractDynamic %2 %5 %10
-)");
-}
-
-TEST_F(BuilderTest, IndexAccessor_Array_Literal) {
- // let a : array<f32, 3u>;
- // a[2i]
-
- auto* var = Let("a", ty.array<f32, 3>(), Construct(ty.array<f32, 3>(), 0_f, 0.5_f, 1_f));
- auto* expr = IndexAccessor("a", 2_i);
- WrapInFunction(var, expr);
-
- spirv::Builder& b = SanitizeAndBuild();
-
- ASSERT_TRUE(b.Build());
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeFloat 32
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 3
-%5 = OpTypeArray %6 %8
-%9 = OpConstantNull %6
-%10 = OpConstant %6 0.5
-%11 = OpConstant %6 1
-%12 = OpConstantComposite %5 %9 %10 %11
-%13 = OpTypeInt 32 1
-%14 = OpConstant %13 2
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), "");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(%15 = OpCompositeExtract %6 %12 2
-OpReturn
-)");
-
- Validate(b);
-}
-
-TEST_F(BuilderTest, IndexAccessor_Array_Dynamic) {
- // let a : array<f32, 3>;
- // idx : i32
- // a[idx]
-
- auto* var = Let("a", ty.array<f32, 3>(), Construct(ty.array<f32, 3>(), 0_f, 0.5_f, 1_f));
-
- auto* idx = Var("idx", ty.i32());
- auto* expr = IndexAccessor("a", idx);
-
- WrapInFunction(var, idx, expr);
-
- spirv::Builder& b = SanitizeAndBuild();
-
- ASSERT_TRUE(b.Build());
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%6 = OpTypeFloat 32
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 3
-%5 = OpTypeArray %6 %8
-%9 = OpConstantNull %6
-%10 = OpConstant %6 0.5
-%11 = OpConstant %6 1
-%12 = OpConstantComposite %5 %9 %10 %11
-%15 = OpTypeInt 32 1
-%14 = OpTypePointer Function %15
-%16 = OpConstantNull %15
-%18 = OpTypePointer Function %5
-%19 = OpConstantNull %5
-%21 = OpTypePointer Function %6
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%13 = OpVariable %14 Function %16
-%17 = OpVariable %18 Function %19
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(OpStore %17 %12
-%20 = OpLoad %15 %13
-%22 = OpAccessChain %21 %17 %20
-%23 = OpLoad %6 %22
-OpReturn
-)");
-
- Validate(b);
-}
-
-TEST_F(BuilderTest, IndexAccessor_Matrix_Dynamic) {
- // let a : mat2x2<f32>(vec2<f32>(1., 2.), vec2<f32>(3., 4.));
- // idx : i32
- // a[idx]
-
- auto* var = Let("a", ty.mat2x2<f32>(),
- Construct(ty.mat2x2<f32>(), Construct(ty.vec2<f32>(), 1_f, 2_f),
- Construct(ty.vec2<f32>(), 3_f, 4_f)));
-
- auto* idx = Var("idx", ty.i32());
- auto* expr = IndexAccessor("a", idx);
-
- WrapInFunction(var, idx, expr);
-
- spirv::Builder& b = SanitizeAndBuild();
-
- ASSERT_TRUE(b.Build());
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
-%1 = OpTypeFunction %2
-%7 = OpTypeFloat 32
-%6 = OpTypeVector %7 2
-%5 = OpTypeMatrix %6 2
-%8 = OpConstant %7 1
-%9 = OpConstant %7 2
-%10 = OpConstantComposite %6 %8 %9
-%11 = OpConstant %7 3
-%12 = OpConstant %7 4
-%13 = OpConstantComposite %6 %11 %12
-%14 = OpConstantComposite %5 %10 %13
-%17 = OpTypeInt 32 1
-%16 = OpTypePointer Function %17
-%18 = OpConstantNull %17
-%20 = OpTypePointer Function %5
-%21 = OpConstantNull %5
-%23 = OpTypePointer Function %6
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
- R"(%15 = OpVariable %16 Function %18
-%19 = OpVariable %20 Function %21
-)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
- R"(OpStore %19 %14
-%22 = OpLoad %17 %15
-%24 = OpAccessChain %23 %19 %22
-%25 = OpLoad %6 %24
+ R"(%23 = OpAccessChain %22 %5 %19 %20 %21 %20 %20
+%25 = OpLoad %12 %23
+%26 = OpVectorShuffle %24 %25 %25 1 0
OpReturn
)");
diff --git a/src/tint/writer/spirv/builder_assign_test.cc b/src/tint/writer/spirv/builder_assign_test.cc
index 71c958c..526ede8 100644
--- a/src/tint/writer/spirv/builder_assign_test.cc
+++ b/src/tint/writer/spirv/builder_assign_test.cc
@@ -23,7 +23,7 @@
using BuilderTest = TestHelper;
TEST_F(BuilderTest, Assign_Var) {
- auto* v = Global("var", ty.f32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
auto* assign = Assign("var", 1_f);
@@ -51,7 +51,7 @@
}
TEST_F(BuilderTest, Assign_Var_OutsideFunction_IsError) {
- auto* v = Global("var", ty.f32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
auto* assign = Assign("var", Expr(1_f));
@@ -70,7 +70,7 @@
}
TEST_F(BuilderTest, Assign_Var_ZeroConstructor) {
- auto* v = Global("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* val = vec3<f32>();
auto* assign = Assign("var", val);
@@ -101,7 +101,7 @@
TEST_F(BuilderTest, Assign_Var_Complex_ConstructorNestedVector) {
auto* init = vec3<f32>(vec2<f32>(1_f, 2_f), 3_f);
- auto* v = Global("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* assign = Assign("var", init);
@@ -134,7 +134,7 @@
TEST_F(BuilderTest, Assign_Var_Complex_Constructor) {
auto* init = vec3<f32>(1_f, 2_f, 3_f);
- auto* v = Global("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* assign = Assign("var", init);
@@ -209,7 +209,7 @@
}
TEST_F(BuilderTest, Assign_Vector) {
- auto* v = Global("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* val = vec3<f32>(1_f, 1_f, 3_f);
auto* assign = Assign("var", val);
@@ -243,7 +243,7 @@
TEST_F(BuilderTest, Assign_Vector_MemberByName) {
// var.y = 1
- auto* v = Global("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* assign = Assign(MemberAccessor("var", "y"), Expr(1_f));
@@ -278,7 +278,7 @@
TEST_F(BuilderTest, Assign_Vector_MemberByIndex) {
// var[1] = 1
- auto* v = Global("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* assign = Assign(IndexAccessor("var", 1_i), Expr(1_f));
diff --git a/src/tint/writer/spirv/builder_binary_expression_test.cc b/src/tint/writer/spirv/builder_binary_expression_test.cc
index abaee2e..443e786 100644
--- a/src/tint/writer/spirv/builder_binary_expression_test.cc
+++ b/src/tint/writer/spirv/builder_binary_expression_test.cc
@@ -287,7 +287,7 @@
EXPECT_EQ(b.GenerateBinaryExpression(expr), 7u) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
%1 = OpTypeVector %2 3
-%3 = OpConstantFalse %2
+%3 = OpConstantNull %2
%4 = OpConstantTrue %2
%5 = OpConstantComposite %1 %3 %4 %3
%6 = OpConstantComposite %1 %4 %3 %4
@@ -704,8 +704,8 @@
}
TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) {
- auto* a_var = Global("a", ty.bool_(), ast::StorageClass::kPrivate, Expr(true));
- auto* b_var = Global("b", ty.bool_(), ast::StorageClass::kPrivate, Expr(false));
+ auto* a_var = GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate, Expr(true));
+ auto* b_var = GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate, Expr(false));
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b"));
@@ -857,8 +857,8 @@
}
TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) {
- auto* a_var = Global("a", ty.bool_(), ast::StorageClass::kPrivate, Expr(true));
- auto* b_var = Global("b", ty.bool_(), ast::StorageClass::kPrivate, Expr(false));
+ auto* a_var = GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate, Expr(true));
+ auto* b_var = GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate, Expr(false));
auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("b"));
diff --git a/src/tint/writer/spirv/builder_builtin_test.cc b/src/tint/writer/spirv/builder_builtin_test.cc
index 4f6dca8..c4bf27e 100644
--- a/src/tint/writer/spirv/builder_builtin_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_test.cc
@@ -41,7 +41,7 @@
using BuiltinBoolTest = BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(BuiltinBoolTest, Call_Bool_Scalar) {
auto param = GetParam();
- auto* var = Global("v", ty.bool_(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -67,7 +67,7 @@
TEST_P(BuiltinBoolTest, Call_Bool_Vector) {
auto param = GetParam();
- auto* var = Global("v", ty.vec3<bool>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.vec3<bool>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -102,7 +102,7 @@
using BuiltinIntTest = BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(BuiltinIntTest, Call_SInt_Scalar) {
auto param = GetParam();
- auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -132,7 +132,7 @@
TEST_P(BuiltinIntTest, Call_SInt_Vector) {
auto param = GetParam();
- auto* var = Global("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -163,7 +163,7 @@
TEST_P(BuiltinIntTest, Call_UInt_Scalar) {
auto param = GetParam();
- auto* var = Global("v", ty.u32(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.u32(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -193,7 +193,7 @@
TEST_P(BuiltinIntTest, Call_UInt_Vector) {
auto param = GetParam();
- auto* var = Global("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -227,7 +227,7 @@
BuiltinData{"reverseBits", "OpBitReverse"}));
TEST_F(BuiltinBuilderTest, Call_Dot_F32) {
- auto* var = Global("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "v", "v");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -256,7 +256,7 @@
}
TEST_F(BuiltinBuilderTest, Call_Dot_U32) {
- auto* var = Global("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "v", "v");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -295,7 +295,7 @@
}
TEST_F(BuiltinBuilderTest, Call_Dot_I32) {
- auto* var = Global("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "v", "v");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -336,7 +336,7 @@
using BuiltinDeriveTest = BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(BuiltinDeriveTest, Call_Derivative_Scalar) {
auto param = GetParam();
- auto* var = Global("v", ty.f32(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
auto* func =
Func("func", {}, ty.void_(), {CallStmt(expr)}, {Stage(ast::PipelineStage::kFragment)});
@@ -364,7 +364,7 @@
TEST_P(BuiltinDeriveTest, Call_Derivative_Vector) {
auto param = GetParam();
- auto* var = Global("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
auto* func =
Func("func", {}, ty.void_(), {CallStmt(expr)}, {Stage(ast::PipelineStage::kFragment)});
@@ -409,9 +409,9 @@
BuiltinData{"fwidthCoarse", "OpFwidthCoarse"}));
TEST_F(BuiltinBuilderTest, Call_Select) {
- auto* v3 = Global("v3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* v3 = GlobalVar("v3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
- auto* bool_v3 = Global("bool_v3", ty.vec3<bool>(), ast::StorageClass::kPrivate);
+ auto* bool_v3 = GlobalVar("bool_v3", ty.vec3<bool>(), ast::StorageClass::kPrivate);
auto* expr = Call("select", "v3", "v3", "bool_v3");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -451,17 +451,17 @@
auto* s = ty.sampler(ast::SamplerKind::kComparisonSampler);
auto* t = ty.depth_texture(ast::TextureDimension::k2d);
- auto* tex = Global("texture", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* tex = GlobalVar("texture", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
- auto* sampler = Global("sampler", s,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(0),
- });
+ auto* sampler = GlobalVar("sampler", s,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(0u),
+ });
auto* expr1 = Call("textureSampleCompare", "texture", "sampler", vec2<f32>(1_f, 2_f), 2_f);
auto* expr2 = Call("textureSampleCompare", "texture", "sampler", vec2<f32>(1_f, 2_f), 2_f);
@@ -506,7 +506,7 @@
}
TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad) {
- auto* var = Global("ident", ty.f32(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("ident", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call("round", "ident");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -1513,7 +1513,7 @@
}
TEST_F(BuiltinBuilderTest, Call_Determinant) {
- auto* var = Global("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("determinant", "var");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -1548,7 +1548,7 @@
}
TEST_F(BuiltinBuilderTest, Call_Transpose) {
- auto* var = Global("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("transpose", "var");
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -1585,11 +1585,11 @@
TEST_F(BuiltinBuilderTest, Call_ArrayLength) {
auto* s = Structure("my_struct", {Member("a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
auto* expr = Call("arrayLength", AddressOf(MemberAccessor("b", "a")));
Func("a_func", {}, ty.void_(),
@@ -1632,11 +1632,11 @@
Member("z", ty.f32()),
Member(4, "a", ty.array<f32>(4)),
});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
auto* expr = Call("arrayLength", AddressOf(MemberAccessor("b", "a")));
Func("a_func", {}, ty.void_(),
@@ -1676,11 +1676,11 @@
TEST_F(BuiltinBuilderTest, Call_ArrayLength_ViaLets) {
auto* s = Structure("my_struct", {Member("a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
auto* p = Let("p", nullptr, AddressOf("b"));
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
@@ -1736,11 +1736,11 @@
// arrayLength(&*p3);
// }
auto* s = Structure("my_struct", {Member("a", ty.array<f32>(4))});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
auto* p = Let("p", nullptr, AddressOf(Deref(AddressOf("b"))));
auto* p2 = Let("p2", nullptr, AddressOf(Deref(p)));
@@ -1801,11 +1801,11 @@
Member("u", ty.atomic<u32>()),
Member("i", ty.atomic<i32>()),
});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
ast::StatementList{
@@ -1865,11 +1865,11 @@
Member("u", ty.atomic<u32>()),
Member("i", ty.atomic<i32>()),
});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
ast::StatementList{
@@ -1937,11 +1937,11 @@
auto* s = Structure("S", {
Member("v", ty.atomic<i32>()),
});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
ast::StatementList{
@@ -2010,11 +2010,11 @@
auto* s = Structure("S", {
Member("v", ty.atomic<u32>()),
});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
ast::StatementList{
@@ -2085,11 +2085,11 @@
Member("u", ty.atomic<u32>()),
Member("i", ty.atomic<i32>()),
});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
ast::StatementList{
@@ -2161,11 +2161,11 @@
Member("u", ty.atomic<u32>()),
Member("i", ty.atomic<i32>()),
});
- Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
Func("a_func", {}, ty.void_(),
ast::StatementList{
diff --git a/src/tint/writer/spirv/builder_builtin_texture_test.cc b/src/tint/writer/spirv/builder_builtin_texture_test.cc
index b4abfcf..ea81211 100644
--- a/src/tint/writer/spirv/builder_builtin_texture_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_texture_test.cc
@@ -2683,7 +2683,7 @@
%26 = OpConstantComposite %14 %23 %24 %25
%28 = OpTypeInt 32 1
%27 = OpTypeVector %28 3
-%29 = OpConstant %28 0
+%29 = OpConstantNull %28
%30 = OpConstant %28 1
%31 = OpConstant %28 2
%32 = OpConstantComposite %27 %29 %30 %31
diff --git a/src/tint/writer/spirv/builder_constructor_expression_test.cc b/src/tint/writer/spirv/builder_constructor_expression_test.cc
index d1fba8f..d8cb809 100644
--- a/src/tint/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_constructor_expression_test.cc
@@ -24,7 +24,7 @@
TEST_F(SpvBuilderConstructorTest, Const) {
auto* c = Expr(42.2_f);
- auto* g = Global("g", ty.f32(), c, ast::StorageClass::kPrivate);
+ auto* g = GlobalVar("g", ty.f32(), c, ast::StorageClass::kPrivate);
spirv::Builder& b = Build();
@@ -439,7 +439,7 @@
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
%1 = OpTypeVector %2 3
%3 = OpConstantTrue %2
-%4 = OpConstantFalse %2
+%4 = OpConstantNull %2
%5 = OpConstantComposite %1 %3 %4 %3
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
@@ -1073,39 +1073,108 @@
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_F32_With_F32) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_F32_With_F32) {
auto* ctor = Construct<f32>(2_f);
GlobalConst("g", ty.f32(), ctor);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeFloat 32
+%6 = OpConstant %5 2
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_F32_With_F32) {
+ auto* ctor = Construct<f32>(2_f);
+ GlobalVar("g", ty.f32(), ast::StorageClass::kPrivate, ctor);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2
-%4 = OpTypeVoid
-%3 = OpTypeFunction %4
+%4 = OpTypePointer Private %1
+%3 = OpVariable %4 Private %2
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
)");
Validate(b);
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_U32_With_F32) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_U32_With_F32) {
auto* ctor = Construct<u32>(1.5_f);
GlobalConst("g", ty.u32(), ctor);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%5 = OpTypeInt 32 0
+%6 = OpConstant %5 1
+%8 = OpTypePointer Function %5
+%9 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_U32_With_F32) {
+ auto* ctor = Construct<u32>(1.5_f);
+ GlobalVar("g", ty.u32(), ast::StorageClass::kPrivate, ctor);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 1
-%4 = OpTypeVoid
-%3 = OpTypeFunction %4
+%4 = OpTypePointer Private %1
+%3 = OpVariable %4 Private %2
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
)");
Validate(b);
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec2_With_F32) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec2_With_F32) {
auto* cast = vec2<f32>(2_f);
- auto* g = Global("g", ty.vec2<f32>(), cast, ast::StorageClass::kPrivate);
+ GlobalConst("g", ty.vec2<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec2_With_F32) {
+ auto* cast = vec2<f32>(2_f);
+ auto* g = GlobalVar("g", ty.vec2<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
@@ -1119,9 +1188,32 @@
)");
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec2_With_Vec2) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec2_With_Vec2) {
auto* cast = vec2<f32>(vec2<f32>(2_f, 2_f));
- GlobalConst("a", ty.vec2<f32>(), cast);
+ GlobalConst("g", ty.vec2<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 2
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec2_With_Vec2) {
+ auto* cast = vec2<f32>(vec2<f32>(2_f, 2_f));
+ GlobalVar("a", ty.vec2<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
@@ -1130,16 +1222,41 @@
%1 = OpTypeVector %2 2
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
+%6 = OpTypePointer Private %1
+%5 = OpVariable %6 Private %4
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
)");
Validate(b);
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_Vec3) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec3_With_Vec3) {
auto* cast = vec3<f32>(vec3<f32>(2_f, 2_f, 2_f));
- GlobalConst("a", ty.vec3<f32>(), cast);
+ GlobalConst("g", ty.vec3<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 3
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_Vec3) {
+ auto* cast = vec3<f32>(vec3<f32>(2_f, 2_f, 2_f));
+ GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
@@ -1148,16 +1265,40 @@
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
+%6 = OpTypePointer Private %1
+%5 = OpVariable %6 Private %4
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
)");
Validate(b);
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec4) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_Vec4) {
auto* cast = vec4<f32>(vec4<f32>(2_f, 2_f, 2_f, 2_f));
- GlobalConst("a", ty.vec4<f32>(), cast);
+ GlobalConst("g", ty.vec4<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 4
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_Vec4) {
+ auto* cast = vec4<f32>(vec4<f32>(2_f, 2_f, 2_f, 2_f));
+ GlobalVar("a", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
@@ -1166,16 +1307,41 @@
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
-%6 = OpTypeVoid
-%5 = OpTypeFunction %6
+%6 = OpTypePointer Private %1
+%5 = OpVariable %6 Private %4
+%8 = OpTypeVoid
+%7 = OpTypeFunction %8
)");
Validate(b);
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_F32) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec3_With_F32) {
auto* cast = vec3<f32>(2_f);
- auto* g = Global("g", ty.vec3<f32>(), cast, ast::StorageClass::kPrivate);
+ GlobalConst("g", ty.vec3<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 3
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_F32) {
+ auto* cast = vec3<f32>(2_f);
+ auto* g = GlobalVar("g", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
@@ -1189,55 +1355,110 @@
)");
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_F32_Vec2) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec3_With_F32_Vec2) {
auto* cast = vec3<f32>(2_f, vec2<f32>(2_f, 2_f));
- auto* g = Global("g", ty.vec3<f32>(), cast, ast::StorageClass::kPrivate);
+ GlobalConst("g", ty.vec3<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 3
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_F32_Vec2) {
+ auto* cast = vec3<f32>(2_f, vec2<f32>(2_f, 2_f));
+ auto* g = GlobalVar("g", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
- EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
+ EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
-%4 = OpTypeVector %2 2
-%5 = OpConstantComposite %4 %3 %3
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%6 = OpSpecConstantOp %2 CompositeExtract %5 8
-%10 = OpConstant %7 1
-%9 = OpSpecConstantOp %2 CompositeExtract %5 10
-%11 = OpSpecConstantComposite %1 %3 %6 %9
+%4 = OpConstantComposite %1 %3 %3 %3
)");
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_Vec2_F32) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec3_With_Vec2_F32) {
auto* cast = vec3<f32>(vec2<f32>(2_f, 2_f), 2_f);
- auto* g = Global("g", ty.vec3<f32>(), cast, ast::StorageClass::kPrivate);
+ GlobalConst("g", ty.vec3<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 3
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_Vec2_F32) {
+ auto* cast = vec3<f32>(vec2<f32>(2_f, 2_f), 2_f);
+ auto* g = GlobalVar("g", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
- EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
+ EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
-%3 = OpTypeVector %2 2
-%4 = OpConstant %2 2
-%5 = OpConstantComposite %3 %4 %4
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%6 = OpSpecConstantOp %2 CompositeExtract %5 8
-%10 = OpConstant %7 1
-%9 = OpSpecConstantOp %2 CompositeExtract %5 10
-%11 = OpSpecConstantComposite %1 %6 %9 %4
+%3 = OpConstant %2 2
+%4 = OpConstantComposite %1 %3 %3 %3
)");
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_F32) {
auto* cast = vec4<f32>(2_f);
- auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
+ GlobalConst("g", ty.vec4<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 4
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32) {
+ auto* cast = vec4<f32>(2_f);
+ auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
@@ -1251,147 +1472,237 @@
)");
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32_F32_Vec2) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_F32_F32_Vec2) {
auto* cast = vec4<f32>(2_f, 2_f, vec2<f32>(2_f, 2_f));
- auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
+ GlobalConst("g", ty.vec4<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 4
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32_F32_Vec2) {
+ auto* cast = vec4<f32>(2_f, 2_f, vec2<f32>(2_f, 2_f));
+ auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
- EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
+ EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
-%4 = OpTypeVector %2 2
-%5 = OpConstantComposite %4 %3 %3
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%6 = OpSpecConstantOp %2 CompositeExtract %5 8
-%10 = OpConstant %7 1
-%9 = OpSpecConstantOp %2 CompositeExtract %5 10
-%11 = OpSpecConstantComposite %1 %3 %3 %6 %9
+%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32_Vec2_F32) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_F32_Vec2_F32) {
auto* cast = vec4<f32>(2_f, vec2<f32>(2_f, 2_f), 2_f);
- auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
+ GlobalConst("g", ty.vec4<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 4
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32_Vec2_F32) {
+ auto* cast = vec4<f32>(2_f, vec2<f32>(2_f, 2_f), 2_f);
+ auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
- EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
+ EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
-%4 = OpTypeVector %2 2
-%5 = OpConstantComposite %4 %3 %3
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%6 = OpSpecConstantOp %2 CompositeExtract %5 8
-%10 = OpConstant %7 1
-%9 = OpSpecConstantOp %2 CompositeExtract %5 10
-%11 = OpSpecConstantComposite %1 %3 %6 %9 %3
+%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec2_F32_F32) {
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_Vec2_F32_F32) {
auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), 2_f, 2_f);
- auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
+ GlobalConst("g", ty.vec4<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
- b.push_function(Function{});
- EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
-%1 = OpTypeVector %2 4
-%3 = OpTypeVector %2 2
-%4 = OpConstant %2 2
-%5 = OpConstantComposite %3 %4 %4
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%6 = OpSpecConstantOp %2 CompositeExtract %5 8
-%10 = OpConstant %7 1
-%9 = OpSpecConstantOp %2 CompositeExtract %5 10
-%11 = OpSpecConstantComposite %1 %6 %9 %4 %4
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 4
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec2_Vec2) {
- auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), vec2<f32>(2_f, 2_f));
- auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_Vec2_F32_F32) {
+ auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), 2_f, 2_f);
+ auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
- EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 13u);
-
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
-%1 = OpTypeVector %2 4
-%3 = OpTypeVector %2 2
-%4 = OpConstant %2 2
-%5 = OpConstantComposite %3 %4 %4
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%6 = OpSpecConstantOp %2 CompositeExtract %5 8
-%10 = OpConstant %7 1
-%9 = OpSpecConstantOp %2 CompositeExtract %5 10
-%11 = OpSpecConstantOp %2 CompositeExtract %5 8
-%12 = OpSpecConstantOp %2 CompositeExtract %5 10
-%13 = OpSpecConstantComposite %1 %6 %9 %11 %12
-)");
-}
-
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32_Vec3) {
- auto* cast = vec4<f32>(2_f, vec3<f32>(2_f, 2_f, 2_f));
- auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
-
- spirv::Builder& b = Build();
-
- b.push_function(Function{});
- EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 13u);
+ EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
-%4 = OpTypeVector %2 3
-%5 = OpConstantComposite %4 %3 %3 %3
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%6 = OpSpecConstantOp %2 CompositeExtract %5 8
-%10 = OpConstant %7 1
-%9 = OpSpecConstantOp %2 CompositeExtract %5 10
-%12 = OpConstant %7 2
-%11 = OpSpecConstantOp %2 CompositeExtract %5 12
-%13 = OpSpecConstantComposite %1 %3 %6 %9 %11
+%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
-TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec3_F32) {
- auto* cast = vec4<f32>(vec3<f32>(2_f, 2_f, 2_f), 2_f);
- auto* g = Global("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_Vec2_Vec2) {
+ auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), vec2<f32>(2_f, 2_f));
+ GlobalConst("g", ty.vec4<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 4
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_Vec2_Vec2) {
+ auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), vec2<f32>(2_f, 2_f));
+ auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
- EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 13u);
+ EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
-%3 = OpTypeVector %2 3
-%4 = OpConstant %2 2
-%5 = OpConstantComposite %3 %4 %4 %4
-%7 = OpTypeInt 32 0
-%8 = OpConstant %7 0
-%6 = OpSpecConstantOp %2 CompositeExtract %5 8
-%10 = OpConstant %7 1
-%9 = OpSpecConstantOp %2 CompositeExtract %5 10
-%12 = OpConstant %7 2
-%11 = OpSpecConstantOp %2 CompositeExtract %5 12
-%13 = OpSpecConstantComposite %1 %6 %9 %11 %4
+%3 = OpConstant %2 2
+%4 = OpConstantComposite %1 %3 %3 %3 %3
+)");
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_F32_Vec3) {
+ auto* cast = vec4<f32>(2_f, vec3<f32>(2_f, 2_f, 2_f));
+ GlobalConst("g", ty.vec4<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 4
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32_Vec3) {
+ auto* cast = vec4<f32>(2_f, vec3<f32>(2_f, 2_f, 2_f));
+ auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
+
+ spirv::Builder& b = Build();
+
+ b.push_function(Function{});
+ EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+%1 = OpTypeVector %2 4
+%3 = OpConstant %2 2
+%4 = OpConstantComposite %1 %3 %3 %3 %3
+)");
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_Vec3_F32) {
+ auto* cast = vec4<f32>(vec3<f32>(2_f, 2_f, 2_f), 2_f);
+ GlobalConst("g", ty.vec4<f32>(), cast);
+ WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
+
+ spirv::Builder& b = SanitizeAndBuild();
+ ASSERT_TRUE(b.Build());
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+%1 = OpTypeFunction %2
+%6 = OpTypeFloat 32
+%5 = OpTypeVector %6 4
+%7 = OpConstant %6 2
+%8 = OpConstantComposite %5 %7 %7 %7 %7
+%10 = OpTypePointer Function %5
+%11 = OpConstantNull %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+OpReturn
+)");
+ Validate(b);
+}
+
+TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_Vec3_F32) {
+ auto* cast = vec4<f32>(vec3<f32>(2_f, 2_f, 2_f), 2_f);
+ auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
+
+ spirv::Builder& b = Build();
+
+ b.push_function(Function{});
+ EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+%1 = OpTypeVector %2 4
+%3 = OpConstant %2 2
+%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
@@ -1990,7 +2301,7 @@
}
TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_U32_to_I32) {
- auto* var = Global("i", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("i", ty.vec3<u32>(), ast::StorageClass::kPrivate);
auto* cast = vec3<i32>("i");
WrapInFunction(cast);
@@ -2016,7 +2327,7 @@
}
TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_F32_to_I32) {
- auto* var = Global("i", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("i", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* cast = vec3<i32>("i");
WrapInFunction(cast);
@@ -2042,7 +2353,7 @@
}
TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_I32_to_U32) {
- auto* var = Global("i", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("i", ty.vec3<i32>(), ast::StorageClass::kPrivate);
auto* cast = vec3<u32>("i");
WrapInFunction(cast);
@@ -2068,7 +2379,7 @@
}
TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_F32_to_U32) {
- auto* var = Global("i", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("i", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* cast = vec3<u32>("i");
WrapInFunction(cast);
@@ -2094,7 +2405,7 @@
}
TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_I32_to_F32) {
- auto* var = Global("i", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("i", ty.vec3<i32>(), ast::StorageClass::kPrivate);
auto* cast = vec3<f32>("i");
WrapInFunction(cast);
@@ -2120,7 +2431,7 @@
}
TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_U32_to_F32) {
- auto* var = Global("i", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("i", ty.vec3<u32>(), ast::StorageClass::kPrivate);
auto* cast = vec3<f32>("i");
WrapInFunction(cast);
@@ -2208,9 +2519,9 @@
TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Vector_WithIdent) {
// vec3<f32>(a, b, c) -> false
- Global("a", ty.f32(), ast::StorageClass::kPrivate);
- Global("b", ty.f32(), ast::StorageClass::kPrivate);
- Global("c", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("c", ty.f32(), ast::StorageClass::kPrivate);
auto* t = vec3<f32>("a", "b", "c");
WrapInFunction(t);
@@ -2280,8 +2591,8 @@
Member("b", ty.vec3<f32>()),
});
- Global("a", ty.f32(), ast::StorageClass::kPrivate);
- Global("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* t = Construct(ty.Of(s), "a", "b");
WrapInFunction(t);
diff --git a/src/tint/writer/spirv/builder_function_test.cc b/src/tint/writer/spirv/builder_function_test.cc
index b2744ef..91fa71a 100644
--- a/src/tint/writer/spirv/builder_function_test.cc
+++ b/src/tint/writer/spirv/builder_function_test.cc
@@ -61,7 +61,7 @@
}
TEST_F(BuilderTest, Function_Terminator_ReturnValue) {
- Global("a", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
Func("a_func", {}, ty.f32(), {Return("a")}, {});
@@ -198,11 +198,11 @@
auto* s = Structure("Data", {Member("d", ty.f32())});
- Global("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
diff --git a/src/tint/writer/spirv/builder_function_variable_test.cc b/src/tint/writer/spirv/builder_function_variable_test.cc
index da72233..4a7026a 100644
--- a/src/tint/writer/spirv/builder_function_variable_test.cc
+++ b/src/tint/writer/spirv/builder_function_variable_test.cc
@@ -138,7 +138,7 @@
)");
}
-TEST_F(BuilderTest, FunctionVar_ConstWithVarInitializer) {
+TEST_F(BuilderTest, FunctionVar_LetWithVarInitializer) {
// var v : f32 = 1.0;
// let v2 : f32 = v; // Should generate the load
@@ -173,7 +173,38 @@
)");
}
-TEST_F(BuilderTest, FunctionVar_Const) {
+TEST_F(BuilderTest, FunctionVar_ConstWithVarInitializer) {
+ // const v : f32 = 1.0;
+ // let v2 : f32 = v;
+
+ auto* v = Const("v", ty.f32(), Expr(1_f));
+
+ auto* v2 = Var("v2", ty.f32(), ast::StorageClass::kNone, Expr("v"));
+ WrapInFunction(v, v2);
+
+ spirv::Builder& b = Build();
+
+ b.push_function(Function{});
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v2"
+)");
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+%2 = OpConstant %1 1
+%4 = OpTypePointer Function %1
+%5 = OpConstantNull %1
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ R"(%3 = OpVariable %4 Function %5
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(OpStore %3 %2
+)");
+}
+
+TEST_F(BuilderTest, FunctionVar_Let) {
auto* init = vec3<f32>(1_f, 1_f, 3_f);
auto* v = Let("var", ty.vec3<f32>(), init);
@@ -193,5 +224,20 @@
)");
}
+TEST_F(BuilderTest, FunctionVar_Const) {
+ auto* init = vec3<f32>(1_f, 1_f, 3_f);
+
+ auto* v = Const("var", ty.vec3<f32>(), init);
+
+ WrapInFunction(v);
+
+ spirv::Builder& b = Build();
+
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), ""); // Not a mistake - 'const' is inlined
+}
+
} // namespace
} // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/builder_global_variable_test.cc b/src/tint/writer/spirv/builder_global_variable_test.cc
index 9b30bb1..05f6929 100644
--- a/src/tint/writer/spirv/builder_global_variable_test.cc
+++ b/src/tint/writer/spirv/builder_global_variable_test.cc
@@ -25,7 +25,7 @@
using BuilderTest = TestHelper;
TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
- auto* v = Global("var", ty.f32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
spirv::Builder& b = Build();
@@ -42,7 +42,7 @@
TEST_F(BuilderTest, GlobalVar_WithConstructor) {
auto* init = vec3<f32>(1_f, 1_f, 3_f);
- auto* v = Global("var", ty.vec3<f32>(), ast::StorageClass::kPrivate, init);
+ auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate, init);
spirv::Builder& b = Build();
@@ -61,35 +61,41 @@
)");
}
-TEST_F(BuilderTest, GlobalVar_Const) {
- auto* init = vec3<f32>(1_f, 1_f, 3_f);
+TEST_F(BuilderTest, GlobalConst) {
+ // const c = 42;
+ // var v = c;
- auto* v = GlobalConst("var", ty.vec3<f32>(), init);
+ auto* c = GlobalConst("c", nullptr, Expr(42_a));
+ GlobalVar("v", nullptr, ast::StorageClass::kPrivate, Expr(c));
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %5 "var"
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+%2 = OpConstant %1 42
+%4 = OpTypePointer Private %1
+%3 = OpVariable %4 Private %2
+%6 = OpTypeVoid
+%5 = OpTypeFunction %6
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
-%1 = OpTypeVector %2 3
-%3 = OpConstant %2 1
-%4 = OpConstant %2 3
-%5 = OpConstantComposite %1 %3 %3 %4
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
)");
+
+ Validate(b);
}
-TEST_F(BuilderTest, GlobalVar_Complex_Constructor) {
- auto* init = vec3<f32>(1_f, 2_f, 3_f);
+TEST_F(BuilderTest, GlobalConst_Vec_Constructor) {
+ // const c = vec3<f32>(1f, 2f, 3f);
+ // var v = c;
- auto* v = GlobalConst("var", ty.vec3<f32>(), init);
+ auto* c = GlobalConst("c", nullptr, vec3<f32>(1_f, 2_f, 3_f));
+ GlobalVar("v", nullptr, ast::StorageClass::kPrivate, Expr(c));
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
@@ -97,18 +103,57 @@
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
+%8 = OpTypePointer Private %1
+%7 = OpVariable %8 Private %6
+%10 = OpTypeVoid
+%9 = OpTypeFunction %10
)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+)");
+
+ Validate(b);
}
-TEST_F(BuilderTest, GlobalVar_Complex_ConstructorNestedVector) {
- auto* init = vec3<f32>(vec2<f32>(1_f, 2_f), 3_f);
+TEST_F(BuilderTest, GlobalConst_Vec_AInt_Constructor) {
+ // const c = vec3(1, 2, 3);
+ // var v = c;
- auto* v = GlobalConst("var", ty.vec3<f32>(), init);
+ auto* c = GlobalConst("c", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+ GlobalVar("v", nullptr, ast::StorageClass::kPrivate, Expr(c));
- spirv::Builder& b = Build();
+ spirv::Builder& b = SanitizeAndBuild();
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+%1 = OpTypeVector %2 3
+%3 = OpConstant %2 1
+%4 = OpConstant %2 2
+%5 = OpConstant %2 3
+%6 = OpConstantComposite %1 %3 %4 %5
+%8 = OpTypePointer Private %1
+%7 = OpVariable %8 Private %6
+%10 = OpTypeVoid
+%9 = OpTypeFunction %10
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, GlobalConst_Vec_AFloat_Constructor) {
+ // const c = vec3(1.0, 2.0, 3.0);
+ // var v = c;
+
+ auto* c = GlobalConst("c", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+ GlobalVar("v", nullptr, ast::StorageClass::kPrivate, Expr(c));
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
@@ -116,16 +161,54 @@
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
+%8 = OpTypePointer Private %1
+%7 = OpVariable %8 Private %6
+%10 = OpTypeVoid
+%9 = OpTypeFunction %10
)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+)");
+
+ Validate(b);
+}
+
+TEST_F(BuilderTest, GlobalConst_Nested_Vec_Constructor) {
+ // const c = vec3<f32>(vec2<f32>(1f, 2f), 3f));
+ // var v = c;
+
+ auto* c = GlobalConst("c", nullptr, vec3<f32>(vec2<f32>(1_f, 2_f), 3_f));
+ GlobalVar("v", nullptr, ast::StorageClass::kPrivate, Expr(c));
+
+ spirv::Builder& b = SanitizeAndBuild();
+
+ ASSERT_TRUE(b.Build()) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+%1 = OpTypeVector %2 3
+%3 = OpConstant %2 1
+%4 = OpConstant %2 2
+%5 = OpConstant %2 3
+%6 = OpConstantComposite %1 %3 %4 %5
+%8 = OpTypePointer Private %1
+%7 = OpVariable %8 Private %6
+%10 = OpTypeVoid
+%9 = OpTypeFunction %10
+)");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+)");
+
+ Validate(b);
}
TEST_F(BuilderTest, GlobalVar_WithBindingAndGroup) {
auto* v =
- Global("var", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone, nullptr,
- ast::AttributeList{
- create<ast::BindingAttribute>(2),
- create<ast::GroupAttribute>(3),
- });
+ GlobalVar("var", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone, nullptr,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(2u),
+ create<ast::GroupAttribute>(3u),
+ });
spirv::Builder& b = Build();
@@ -365,11 +448,11 @@
Member("b", ty.i32()),
});
- Global("b", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("b", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -406,11 +489,11 @@
auto* A = Structure("A", {Member("a", ty.i32())});
auto* B = Alias("B", ty.Of(A));
- Global("b", ty.Of(B), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("b", ty.Of(B), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -445,11 +528,11 @@
auto* A = Structure("A", {Member("a", ty.i32())});
auto* B = Alias("B", ty.Of(A));
- Global("b", ty.Of(B), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("b", ty.Of(B), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -483,16 +566,16 @@
// var<storage, read_write> c : A
auto* A = Structure("A", {Member("a", ty.i32())});
- Global("b", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::GroupAttribute>(0),
- create<ast::BindingAttribute>(0),
- });
- Global("c", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::GroupAttribute>(1),
- create<ast::BindingAttribute>(0),
- });
+ GlobalVar("b", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::GroupAttribute>(0u),
+ create<ast::BindingAttribute>(0u),
+ });
+ GlobalVar("c", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::GroupAttribute>(1u),
+ create<ast::BindingAttribute>(0u),
+ });
spirv::Builder& b = SanitizeAndBuild();
@@ -529,11 +612,11 @@
auto* type = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
ast::Access::kWrite);
- auto* var_a = Global("a", type,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* var_a = GlobalVar("a", type,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
@@ -560,19 +643,19 @@
auto* type_a = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
ast::Access::kReadWrite);
- auto* var_a = Global("a", type_a, ast::StorageClass::kNone,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* var_a = GlobalVar("a", type_a, ast::StorageClass::kNone,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
auto* type_b = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
ast::Access::kWrite);
- auto* var_b = Global("b", type_b, ast::StorageClass::kNone,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(0),
- });
+ auto* var_b = GlobalVar("b", type_b, ast::StorageClass::kNone,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
@@ -599,16 +682,16 @@
TEST_F(BuilderTest, GlobalVar_WorkgroupWithZeroInit) {
auto* type_scalar = ty.i32();
- auto* var_scalar = Global("a", type_scalar, ast::StorageClass::kWorkgroup);
+ auto* var_scalar = GlobalVar("a", type_scalar, ast::StorageClass::kWorkgroup);
auto* type_array = ty.array<f32, 16>();
- auto* var_array = Global("b", type_array, ast::StorageClass::kWorkgroup);
+ auto* var_array = GlobalVar("b", type_array, ast::StorageClass::kWorkgroup);
auto* type_struct = Structure("C", {
Member("a", ty.i32()),
Member("b", ty.i32()),
});
- auto* var_struct = Global("c", ty.Of(type_struct), ast::StorageClass::kWorkgroup);
+ auto* var_struct = GlobalVar("c", ty.Of(type_struct), ast::StorageClass::kWorkgroup);
program = std::make_unique<Program>(std::move(*this));
diff --git a/src/tint/writer/spirv/builder_ident_expression_test.cc b/src/tint/writer/spirv/builder_ident_expression_test.cc
index e2e9826..0f24146 100644
--- a/src/tint/writer/spirv/builder_ident_expression_test.cc
+++ b/src/tint/writer/spirv/builder_ident_expression_test.cc
@@ -25,9 +25,9 @@
TEST_F(BuilderTest, IdentifierExpression_GlobalConst) {
auto* init = vec3<f32>(1_f, 1_f, 3_f);
- auto* v = GlobalConst("var", ty.vec3<f32>(), init);
+ auto* v = GlobalConst("c", ty.vec3<f32>(), init);
- auto* expr = Expr("var");
+ auto* expr = Expr("c");
WrapInFunction(expr);
spirv::Builder& b = Build();
@@ -35,18 +35,13 @@
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
-%1 = OpTypeVector %2 3
-%3 = OpConstant %2 1
-%4 = OpConstant %2 3
-%5 = OpConstantComposite %1 %3 %3 %4
-)");
+ EXPECT_EQ(DumpInstructions(b.types()), R"()");
- EXPECT_EQ(b.GenerateIdentifierExpression(expr), 5u);
+ EXPECT_EQ(b.GenerateIdentifierExpression(expr), 0u);
}
TEST_F(BuilderTest, IdentifierExpression_GlobalVar) {
- auto* v = Global("var", ty.f32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Expr("var");
WrapInFunction(expr);
@@ -114,8 +109,7 @@
}
TEST_F(BuilderTest, IdentifierExpression_Load) {
- auto* var = Global("var", ty.i32(), ast::StorageClass::kPrivate);
-
+ auto* var = GlobalVar("var", ty.i32(), ast::StorageClass::kPrivate);
auto* expr = Add("var", "var");
WrapInFunction(expr);
@@ -138,15 +132,14 @@
}
TEST_F(BuilderTest, IdentifierExpression_NoLoadConst) {
- auto* var = GlobalConst("var", ty.i32(), Expr(2_i));
-
- auto* expr = Add("var", "var");
- WrapInFunction(expr);
+ auto* let = Let("let", ty.i32(), Expr(2_i));
+ auto* expr = Add("let", "let");
+ WrapInFunction(let, expr);
spirv::Builder& b = Build();
b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+ ASSERT_TRUE(b.GenerateFunctionVariable(let)) << b.error();
EXPECT_EQ(b.GenerateBinaryExpression(expr->As<ast::BinaryExpression>()), 3u) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
diff --git a/src/tint/writer/spirv/builder_if_test.cc b/src/tint/writer/spirv/builder_if_test.cc
index 8c7c8ee..391be43 100644
--- a/src/tint/writer/spirv/builder_if_test.cc
+++ b/src/tint/writer/spirv/builder_if_test.cc
@@ -68,7 +68,7 @@
// v = 2;
// }
- auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* body = Block(Assign("v", 2_i));
auto* expr = If(true, body);
WrapInFunction(expr);
@@ -104,7 +104,7 @@
// v = 3i;
// }
- auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* body = Block(Assign("v", 2_i));
auto* else_body = Block(Assign("v", 3_i));
@@ -146,7 +146,7 @@
// v = 3i;
// }
- auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* body = Block(Assign("v", 2_i));
auto* else_body = Block(Assign("v", 3_i));
@@ -197,7 +197,7 @@
// v = 5i;
// }
- auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* body = Block(Assign("v", 2_i));
auto* elseif_1_body = Block(Assign("v", 3_i));
auto* elseif_2_body = Block(Assign("v", 4_i));
@@ -559,7 +559,7 @@
// if (a) {
// }
- auto* var = Global("a", ty.bool_(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
auto* fn = Func("f", {}, ty.void_(), {If("a", Block())});
spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/builder_loop_test.cc b/src/tint/writer/spirv/builder_loop_test.cc
index b4c2baa..ae9e408 100644
--- a/src/tint/writer/spirv/builder_loop_test.cc
+++ b/src/tint/writer/spirv/builder_loop_test.cc
@@ -54,7 +54,7 @@
// break;
// }
- auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* body = Block(Assign("v", 2_i), //
Break());
@@ -96,7 +96,7 @@
// }
// }
- auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
auto* body = Block(Assign("v", 2_i), //
Break());
auto* continuing = Block(Assign("v", 3_i));
diff --git a/src/tint/writer/spirv/builder_switch_test.cc b/src/tint/writer/spirv/builder_switch_test.cc
index 7ddd1bd..3c905b6 100644
--- a/src/tint/writer/spirv/builder_switch_test.cc
+++ b/src/tint/writer/spirv/builder_switch_test.cc
@@ -57,8 +57,8 @@
// default: {}
// }
- auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
- auto* a = Global("a", ty.i32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -114,8 +114,8 @@
// default: {}
// }
- auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
- auto* a = Global("a", ty.u32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.u32(), ast::StorageClass::kPrivate);
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -171,8 +171,8 @@
// v = 1i;
// }
- auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
- auto* a = Global("a", ty.i32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -221,8 +221,8 @@
// v = 3i;
// }
- auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
- auto* a = Global("a", ty.i32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -284,8 +284,8 @@
// v = 3i;
// }
- auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
- auto* a = Global("a", ty.i32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
auto* func = Func("a_func", {}, ty.void_(),
{
@@ -346,8 +346,8 @@
// default: {}
// }
- auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
- auto* a = Global("a", ty.i32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
auto* func = Func("a_func", {}, ty.void_(),
{
diff --git a/src/tint/writer/spirv/builder_type_test.cc b/src/tint/writer/spirv/builder_type_test.cc
index 8dc048e..b4bff9b 100644
--- a/src/tint/writer/spirv/builder_type_test.cc
+++ b/src/tint/writer/spirv/builder_type_test.cc
@@ -28,11 +28,11 @@
TEST_F(BuilderTest_Type, GenerateRuntimeArray) {
auto* ary = ty.array(ty.i32());
auto* str = Structure("S", {Member("x", ary)});
- Global("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
@@ -48,11 +48,11 @@
TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) {
auto* ary = ty.array(ty.i32());
auto* str = Structure("S", {Member("x", ary)});
- Global("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
@@ -67,7 +67,7 @@
TEST_F(BuilderTest_Type, GenerateArray) {
auto* ary = ty.array(ty.i32(), 4_u);
- Global("a", ary, ast::StorageClass::kPrivate);
+ GlobalVar("a", ary, ast::StorageClass::kPrivate);
spirv::Builder& b = Build();
@@ -84,7 +84,7 @@
TEST_F(BuilderTest_Type, GenerateArray_WithStride) {
auto* ary = ty.array(ty.i32(), 4_u, 16u);
- Global("a", ary, ast::StorageClass::kPrivate);
+ GlobalVar("a", ary, ast::StorageClass::kPrivate);
spirv::Builder& b = Build();
@@ -104,7 +104,7 @@
TEST_F(BuilderTest_Type, ReturnsGeneratedArray) {
auto* ary = ty.array(ty.i32(), 4_u);
- Global("a", ary, ast::StorageClass::kPrivate);
+ GlobalVar("a", ary, ast::StorageClass::kPrivate);
spirv::Builder& b = Build();
@@ -781,11 +781,11 @@
auto* s = ty.storage_texture(ast::TextureDimension::k1d, ast::TexelFormat::kR32Float,
ast::Access::kWrite);
- Global("test_var", s,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("test_var", s,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
@@ -800,11 +800,11 @@
auto* s = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
ast::Access::kWrite);
- Global("test_var", s,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("test_var", s,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
@@ -819,11 +819,11 @@
auto* s = ty.storage_texture(ast::TextureDimension::k2dArray, ast::TexelFormat::kR32Float,
ast::Access::kWrite);
- Global("test_var", s,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("test_var", s,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
@@ -838,11 +838,11 @@
auto* s = ty.storage_texture(ast::TextureDimension::k3d, ast::TexelFormat::kR32Float,
ast::Access::kWrite);
- Global("test_var", s,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("test_var", s,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
@@ -857,11 +857,11 @@
auto* s = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
ast::Access::kWrite);
- Global("test_var", s,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("test_var", s,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
@@ -876,11 +876,11 @@
auto* s = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Sint,
ast::Access::kWrite);
- Global("test_var", s,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("test_var", s,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
@@ -895,11 +895,11 @@
auto* s = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
ast::Access::kWrite);
- Global("test_var", s,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("test_var", s,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/generator_impl.cc b/src/tint/writer/spirv/generator_impl.cc
index c5e9dad..a435fb8 100644
--- a/src/tint/writer/spirv/generator_impl.cc
+++ b/src/tint/writer/spirv/generator_impl.cc
@@ -46,6 +46,8 @@
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
+ polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
+ polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.count_leading_zeros = true;
polyfills.count_trailing_zeros = true;
polyfills.extract_bits = transform::BuiltinPolyfill::Level::kClampParameters;
diff --git a/src/tint/writer/text_generator.cc b/src/tint/writer/text_generator.cc
index 5e4e93f..1a1fa5a 100644
--- a/src/tint/writer/text_generator.cc
+++ b/src/tint/writer/text_generator.cc
@@ -84,7 +84,7 @@
<< " lines.size(): " << lines.size();
return;
}
- lines.insert(lines.begin() + before, Line{indent, line});
+ lines.insert(lines.begin() + static_cast<int64_t>(before), Line{indent, line});
}
void TextGenerator::TextBuffer::Append(const TextBuffer& tb) {
@@ -105,7 +105,8 @@
size_t idx = 0;
for (auto& line : tb.lines) {
// TODO(bclayton): inefficent, consider optimizing
- lines.insert(lines.begin() + before + idx, Line{indent + line.indent, line.content});
+ lines.insert(lines.begin() + static_cast<int64_t>(before + idx),
+ Line{indent + line.indent, line.content});
idx++;
}
}
diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc
index 7df4fdf..26e0a29 100644
--- a/src/tint/writer/wgsl/generator_impl.cc
+++ b/src/tint/writer/wgsl/generator_impl.cc
@@ -645,14 +645,6 @@
bool ok = Switch(
v, //
- [&](const ast::Let* ) {
- out << "let";
- return true;
- },
- [&](const ast::Override* ) {
- out << "override";
- return true;
- },
[&](const ast::Var* var) {
out << "var";
auto sc = var->declared_storage_class;
@@ -669,6 +661,18 @@
}
return true;
},
+ [&](const ast::Let*) {
+ out << "let";
+ return true;
+ },
+ [&](const ast::Override*) {
+ out << "override";
+ return true;
+ },
+ [&](const ast::Const*) {
+ out << "const";
+ return true;
+ },
[&](Default) {
TINT_ICE(Writer, diagnostics_) << "unhandled variable type " << v->TypeInfo().name;
return false;
@@ -710,7 +714,7 @@
[&](const ast::WorkgroupAttribute* workgroup) {
auto values = workgroup->Values();
out << "workgroup_size(";
- for (int i = 0; i < 3; i++) {
+ for (size_t i = 0; i < 3; i++) {
if (values[i]) {
if (i > 0) {
out << ", ";
diff --git a/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc b/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
index 2b4e8b4..d5f7f9f 100644
--- a/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
@@ -22,7 +22,7 @@
using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, IndexAccessor) {
- Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
+ GlobalVar("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
auto* expr = IndexAccessor("ary", 5_i);
WrapInFunction(expr);
@@ -34,7 +34,7 @@
}
TEST_F(WgslGeneratorImplTest, IndexAccessor_OfDref) {
- Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
+ GlobalVar("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
auto* p = Let("p", nullptr, AddressOf("ary"));
auto* expr = IndexAccessor(Deref("p"), 5_i);
diff --git a/src/tint/writer/wgsl/generator_impl_assign_test.cc b/src/tint/writer/wgsl/generator_impl_assign_test.cc
index 8d5e75e..e390d2f 100644
--- a/src/tint/writer/wgsl/generator_impl_assign_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_assign_test.cc
@@ -20,8 +20,8 @@
using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Assign) {
- auto* lhs = Global("lhs", ty.i32(), ast::StorageClass::kPrivate);
- auto* rhs = Global("rhs", ty.i32(), ast::StorageClass::kPrivate);
+ auto* lhs = GlobalVar("lhs", ty.i32(), ast::StorageClass::kPrivate);
+ auto* rhs = GlobalVar("rhs", ty.i32(), ast::StorageClass::kPrivate);
auto* assign = Assign(lhs, rhs);
WrapInFunction(assign);
diff --git a/src/tint/writer/wgsl/generator_impl_binary_test.cc b/src/tint/writer/wgsl/generator_impl_binary_test.cc
index acc4180..682c001 100644
--- a/src/tint/writer/wgsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_binary_test.cc
@@ -37,8 +37,8 @@
}
};
- Global("left", op_ty(), ast::StorageClass::kPrivate);
- Global("right", op_ty(), ast::StorageClass::kPrivate);
+ GlobalVar("left", op_ty(), ast::StorageClass::kPrivate);
+ GlobalVar("right", op_ty(), ast::StorageClass::kPrivate);
auto* left = Expr("left");
auto* right = Expr("right");
diff --git a/src/tint/writer/wgsl/generator_impl_call_test.cc b/src/tint/writer/wgsl/generator_impl_call_test.cc
index 6a7e077..24f7e4b 100644
--- a/src/tint/writer/wgsl/generator_impl_call_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_call_test.cc
@@ -42,8 +42,8 @@
Param(Sym(), ty.f32()),
},
ty.f32(), {Return(1.23_f)});
- Global("param1", ty.f32(), ast::StorageClass::kPrivate);
- Global("param2", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
auto* call = Call("my_func", "param1", "param2");
WrapInFunction(call);
@@ -62,8 +62,8 @@
Param(Sym(), ty.f32()),
},
ty.void_(), ast::StatementList{}, ast::AttributeList{});
- Global("param1", ty.f32(), ast::StorageClass::kPrivate);
- Global("param2", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
auto* call = Call("my_func", "param1", "param2");
auto* stmt = CallStmt(call);
diff --git a/src/tint/writer/wgsl/generator_impl_function_test.cc b/src/tint/writer/wgsl/generator_impl_function_test.cc
index 74f4a6e..0673858 100644
--- a/src/tint/writer/wgsl/generator_impl_function_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_function_test.cc
@@ -160,11 +160,11 @@
auto* s = Structure("Data", {Member("d", ty.f32())});
- Global("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
{
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
diff --git a/src/tint/writer/wgsl/generator_impl_global_decl_test.cc b/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
index 8f6d4f0..ef9e11c 100644
--- a/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
@@ -28,7 +28,7 @@
auto* func_var = Var("a", ty.f32());
WrapInFunction(func_var);
- Global("a", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -45,7 +45,7 @@
}
TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
- Global("a0", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("a0", ty.f32(), ast::StorageClass::kPrivate);
auto* s0 = Structure("S0", {Member("a", ty.i32())});
@@ -55,7 +55,7 @@
},
{});
- Global("a1", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("a1", ty.f32(), ast::StorageClass::kPrivate);
auto* s1 = Structure("S1", {Member("a", ty.i32())});
@@ -101,11 +101,11 @@
}
TEST_F(WgslGeneratorImplTest, Emit_Global_Sampler) {
- Global("s", ty.sampler(ast::SamplerKind::kSampler),
- ast::AttributeList{
- create<ast::GroupAttribute>(0),
- create<ast::BindingAttribute>(0),
- });
+ GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler),
+ ast::AttributeList{
+ create<ast::GroupAttribute>(0u),
+ create<ast::BindingAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -117,11 +117,11 @@
TEST_F(WgslGeneratorImplTest, Emit_Global_Texture) {
auto* st = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
- Global("t", st,
- ast::AttributeList{
- create<ast::GroupAttribute>(0),
- create<ast::BindingAttribute>(0),
- });
+ GlobalVar("t", st,
+ ast::AttributeList{
+ create<ast::GroupAttribute>(0u),
+ create<ast::BindingAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -131,6 +131,21 @@
EXPECT_EQ(gen.result(), " @group(0) @binding(0) var t : texture_1d<f32>;\n");
}
+TEST_F(WgslGeneratorImplTest, Emit_GlobalConst) {
+ GlobalConst("explicit", ty.f32(), Expr(1_f));
+ GlobalConst("inferred", nullptr, Expr(1_f));
+
+ GeneratorImpl& gen = Build();
+
+ gen.increment_indent();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"( const explicit : f32 = 1.0f;
+
+ const inferred = 1.0f;
+)");
+}
+
TEST_F(WgslGeneratorImplTest, Emit_OverridableConstants) {
Override("a", ty.f32(), nullptr);
Override("b", ty.f32(), nullptr, {Id(7u)});
diff --git a/src/tint/writer/wgsl/generator_impl_identifier_test.cc b/src/tint/writer/wgsl/generator_impl_identifier_test.cc
index c6bccf6..2e20d4c 100644
--- a/src/tint/writer/wgsl/generator_impl_identifier_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_identifier_test.cc
@@ -20,7 +20,7 @@
using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitIdentifierExpression_Single) {
- Global("glsl", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("glsl", ty.f32(), ast::StorageClass::kPrivate);
auto* i = Expr("glsl");
WrapInFunction(i);
diff --git a/src/tint/writer/wgsl/generator_impl_if_test.cc b/src/tint/writer/wgsl/generator_impl_if_test.cc
index 18c0ffd..88f6aba 100644
--- a/src/tint/writer/wgsl/generator_impl_if_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_if_test.cc
@@ -20,7 +20,7 @@
using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_If) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* cond = Expr("cond");
auto* body = Block(Return());
@@ -39,8 +39,8 @@
}
TEST_F(WgslGeneratorImplTest, Emit_IfWithElseIf) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
- Global("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* else_cond = Expr("else_cond");
auto* else_body = Block(Return());
@@ -64,7 +64,7 @@
}
TEST_F(WgslGeneratorImplTest, Emit_IfWithElse) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* else_body = Block(Return());
@@ -87,8 +87,8 @@
}
TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) {
- Global("cond", ty.bool_(), ast::StorageClass::kPrivate);
- Global("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
auto* else_cond = Expr("else_cond");
diff --git a/src/tint/writer/wgsl/generator_impl_literal_test.cc b/src/tint/writer/wgsl/generator_impl_literal_test.cc
index dd715d4..78d70f6 100644
--- a/src/tint/writer/wgsl/generator_impl_literal_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_literal_test.cc
@@ -25,7 +25,7 @@
// - 0 sign if sign is 0, 1 otherwise
// - 'exponent_bits' is placed in the exponent space.
// So, the exponent bias must already be included.
-f32 MakeFloat(int sign, int biased_exponent, int mantissa) {
+f32 MakeFloat(uint32_t sign, uint32_t biased_exponent, uint32_t mantissa) {
const uint32_t sign_bit = sign ? 0x80000000u : 0u;
// The binary32 exponent is 8 bits, just below the sign.
const uint32_t exponent_bits = (biased_exponent & 0xffu) << 23;
diff --git a/src/tint/writer/wgsl/generator_impl_loop_test.cc b/src/tint/writer/wgsl/generator_impl_loop_test.cc
index 3dbae60..3570957 100644
--- a/src/tint/writer/wgsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_loop_test.cc
@@ -68,7 +68,7 @@
// for({ignore(1i); ignore(2i);}; ; ) {
// return;
// }
- Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
auto* multi_stmt = Block(Ignore(1_i), Ignore(2_i));
auto* f = For(multi_stmt, nullptr, nullptr, Block(Return()));
WrapInFunction(f);
@@ -132,7 +132,7 @@
// return;
// }
- Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
auto* multi_stmt = Block(Ignore(1_i), Ignore(2_i));
auto* f = For(nullptr, nullptr, multi_stmt, Block(Return()));
WrapInFunction(f);
@@ -175,7 +175,7 @@
// for({ ignore(1i); ignore(2i); }; true; { ignore(3i); ignore(4i); }) {
// return;
// }
- Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+ GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
auto* multi_stmt_a = Block(Ignore(1_i), Ignore(2_i));
auto* multi_stmt_b = Block(Ignore(3_i), Ignore(4_i));
auto* f = For(multi_stmt_a, Expr(true), multi_stmt_b, Block(Return()));
diff --git a/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc b/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
index d8bd349..34760ba 100644
--- a/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
@@ -21,7 +21,7 @@
TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) {
auto* s = Structure("Data", {Member("mem", ty.f32())});
- Global("str", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("str", "mem");
WrapInFunction(expr);
@@ -35,7 +35,7 @@
TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor_OfDref) {
auto* s = Structure("Data", {Member("mem", ty.f32())});
- Global("str", ty.Of(s), ast::StorageClass::kPrivate);
+ GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
auto* p = Let("p", nullptr, AddressOf("str"));
auto* expr = MemberAccessor(Deref("p"), "mem");
diff --git a/src/tint/writer/wgsl/generator_impl_switch_test.cc b/src/tint/writer/wgsl/generator_impl_switch_test.cc
index 11424f0..141a5d7 100644
--- a/src/tint/writer/wgsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_switch_test.cc
@@ -22,7 +22,7 @@
using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Switch) {
- Global("cond", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("cond", ty.i32(), ast::StorageClass::kPrivate);
auto* def_body = Block(create<ast::BreakStatement>());
auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
diff --git a/src/tint/writer/wgsl/generator_impl_type_test.cc b/src/tint/writer/wgsl/generator_impl_type_test.cc
index 0973ffa..b6ae9c5 100644
--- a/src/tint/writer/wgsl/generator_impl_type_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_type_test.cc
@@ -420,11 +420,11 @@
auto param = GetParam();
auto* t = ty.storage_texture(param.dim, param.fmt, param.access);
- Global("g", t,
- ast::AttributeList{
- create<ast::BindingAttribute>(1),
- create<ast::GroupAttribute>(2),
- });
+ GlobalVar("g", t,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(1u),
+ create<ast::GroupAttribute>(2u),
+ });
GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_unary_op_test.cc b/src/tint/writer/wgsl/generator_impl_unary_op_test.cc
index 2c46b44..b741dc8 100644
--- a/src/tint/writer/wgsl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
using WgslUnaryOpTest = TestHelper;
TEST_F(WgslUnaryOpTest, AddressOf) {
- Global("expr", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.f32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
WrapInFunction(op);
@@ -32,7 +32,7 @@
}
TEST_F(WgslUnaryOpTest, Complement) {
- Global("expr", ty.u32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.u32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
WrapInFunction(op);
@@ -44,7 +44,7 @@
}
TEST_F(WgslUnaryOpTest, Indirection) {
- Global("G", ty.f32(), ast::StorageClass::kPrivate);
+ GlobalVar("G", ty.f32(), ast::StorageClass::kPrivate);
auto* p =
Let("expr", nullptr, create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
@@ -58,7 +58,7 @@
}
TEST_F(WgslUnaryOpTest, Not) {
- Global("expr", ty.bool_(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.bool_(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
WrapInFunction(op);
@@ -70,7 +70,7 @@
}
TEST_F(WgslUnaryOpTest, Negation) {
- Global("expr", ty.i32(), ast::StorageClass::kPrivate);
+ GlobalVar("expr", ty.i32(), ast::StorageClass::kPrivate);
auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
WrapInFunction(op);
diff --git a/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
index a68932c..aeacd30 100644
--- a/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
@@ -50,5 +50,189 @@
EXPECT_EQ(gen.result(), " var a = 123i;\n");
}
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_AInt) {
+ auto* C = Const("C", nullptr, Expr(1_a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = 1;
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_AFloat) {
+ auto* C = Const("C", nullptr, Expr(1._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = 1.0;
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_i32) {
+ auto* C = Const("C", nullptr, Expr(1_i));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = 1i;
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_u32) {
+ auto* C = Const("C", nullptr, Expr(1_u));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = 1u;
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_f32) {
+ auto* C = Const("C", nullptr, Expr(1_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = 1.0f;
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AInt) {
+ auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = vec3(1, 2, 3);
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AFloat) {
+ auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = vec3(1.0, 2.0, 3.0);
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_f32) {
+ auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = vec3<f32>(1.0f, 2.0f, 3.0f);
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
+ auto* C =
+ Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = mat2x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_f32) {
+ auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = mat2x3<f32>(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f);
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_f32) {
+ auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = array<f32, 3u>(1.0f, 2.0f, 3.0f);
+ let l = C;
+}
+)");
+}
+
+TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
+ auto* C = Const("C", nullptr,
+ Construct(ty.array(ty.vec2<bool>(), 3_u), //
+ vec2<bool>(true, false), //
+ vec2<bool>(false, true), //
+ vec2<bool>(true, true)));
+ Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+
+ EXPECT_EQ(gen.result(), R"(fn f() {
+ const C = array<vec2<bool>, 3u>(vec2<bool>(true, false), vec2<bool>(false, true), vec2<bool>(true, true));
+ let l = C;
+}
+)");
+}
} // namespace
} // namespace tint::writer::wgsl
diff --git a/src/tint/writer/wgsl/generator_impl_variable_test.cc b/src/tint/writer/wgsl/generator_impl_variable_test.cc
index 83af7c2..a02aed8 100644
--- a/src/tint/writer/wgsl/generator_impl_variable_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_variable_test.cc
@@ -22,7 +22,7 @@
using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitVariable) {
- auto* v = Global("a", ty.f32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -32,7 +32,7 @@
}
TEST_F(WgslGeneratorImplTest, EmitVariable_StorageClass) {
- auto* v = Global("a", ty.f32(), ast::StorageClass::kPrivate);
+ auto* v = GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -43,11 +43,11 @@
TEST_F(WgslGeneratorImplTest, EmitVariable_Access_Read) {
auto* s = Structure("S", {Member("a", ty.i32())});
- auto* v = Global("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* v = GlobalVar("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -58,11 +58,11 @@
TEST_F(WgslGeneratorImplTest, EmitVariable_Access_Write) {
auto* s = Structure("S", {Member("a", ty.i32())});
- auto* v = Global("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* v = GlobalVar("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -73,11 +73,11 @@
TEST_F(WgslGeneratorImplTest, EmitVariable_Access_ReadWrite) {
auto* s = Structure("S", {Member("a", ty.i32())});
- auto* v = Global("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
- ast::AttributeList{
- create<ast::BindingAttribute>(0),
- create<ast::GroupAttribute>(0),
- });
+ auto* v = GlobalVar("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+ ast::AttributeList{
+ create<ast::BindingAttribute>(0u),
+ create<ast::GroupAttribute>(0u),
+ });
GeneratorImpl& gen = Build();
@@ -87,11 +87,12 @@
}
TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated) {
- auto* v = Global("a", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone, nullptr,
- ast::AttributeList{
- create<ast::GroupAttribute>(1),
- create<ast::BindingAttribute>(2),
- });
+ auto* v =
+ GlobalVar("a", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone, nullptr,
+ ast::AttributeList{
+ create<ast::GroupAttribute>(1u),
+ create<ast::BindingAttribute>(2u),
+ });
GeneratorImpl& gen = Build();
@@ -101,7 +102,7 @@
}
TEST_F(WgslGeneratorImplTest, EmitVariable_Constructor) {
- auto* v = Global("a", ty.f32(), ast::StorageClass::kPrivate, Expr(1_f));
+ auto* v = GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate, Expr(1_f));
GeneratorImpl& gen = Build();
@@ -110,9 +111,9 @@
EXPECT_EQ(out.str(), R"(var<private> a : f32 = 1.0f;)");
}
-TEST_F(WgslGeneratorImplTest, EmitVariable_Const) {
+TEST_F(WgslGeneratorImplTest, EmitVariable_Let_Explicit) {
auto* v = Let("a", ty.f32(), Expr(1_f));
- WrapInFunction(Decl(v));
+ WrapInFunction(v);
GeneratorImpl& gen = Build();
@@ -121,5 +122,38 @@
EXPECT_EQ(out.str(), R"(let a : f32 = 1.0f;)");
}
+TEST_F(WgslGeneratorImplTest, EmitVariable_Let_Inferred) {
+ auto* v = Let("a", nullptr, Expr(1_f));
+ WrapInFunction(v);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitVariable(out, v)) << gen.error();
+ EXPECT_EQ(out.str(), R"(let a = 1.0f;)");
+}
+
+TEST_F(WgslGeneratorImplTest, EmitVariable_Const_Explicit) {
+ auto* v = Const("a", ty.f32(), Expr(1_f));
+ WrapInFunction(v);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitVariable(out, v)) << gen.error();
+ EXPECT_EQ(out.str(), R"(const a : f32 = 1.0f;)");
+}
+
+TEST_F(WgslGeneratorImplTest, EmitVariable_Const_Inferred) {
+ auto* v = Const("a", nullptr, Expr(1_f));
+ WrapInFunction(v);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitVariable(out, v)) << gen.error();
+ EXPECT_EQ(out.str(), R"(const a = 1.0f;)");
+}
+
} // namespace
} // namespace tint::writer::wgsl
diff --git a/test/tint/BUILD.gn b/test/tint/BUILD.gn
deleted file mode 100644
index 0953422..0000000
--- a/test/tint/BUILD.gn
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2022 The Dawn & 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.
-
-group("tint_unittests") {
- testonly = true
- public_deps = [ "../../src/tint:tint_unittests" ]
-}