Import Tint changes from Dawn
Changes:
- 55c0c9d950edb4f45b2f94d5c3e4114fc30609e8 tint: Add abstract numerics to vector and matrix construc... by Ben Clayton <bclayton@google.com>
- d3de38d7e3880a90cbed8f8fb895729e580c8fbd tint: Simplify the resolver constant evaluation by Ben Clayton <bclayton@google.com>
- 8f4f4495408cfde7755be8127180178015bf7d40 tint/writer: Do not attempt to use invalid programs by Ben Clayton <bclayton@google.com>
- 6522837acbf96682583ada4ead5c8e86f28df437 tint: Add `enable_abstract_numerics` flag on Resolver by Ben Clayton <bclayton@google.com>
- 43581f1fb62ced507e1693c2e8959ed342dd7f6a tint: Add new methods to semantic Switch nodes by Ben Clayton <bclayton@google.com>
- a2ce4ecc8b325ff79176a867b6074b6ca733851b tint: Add more helpers to resolver_test_helper.h by Ben Clayton <bclayton@google.com>
- d99af036634c3dc612d18042465bfcc45203fffc tint: Add utils::UniqueVector::data() by Ben Clayton <bclayton@google.com>
- ab4c0357629178ec2c217b4b05ad715142546fe1 tint: fix HLSL countOneBits and reverseBits for i32 args by Antonio Maiorano <amaiorano@google.com>
- e9ce8326b7843be34e8a31a5a54600cb924c83f2 tint: Minor, miscellaneous cleanups by Ben Clayton <bclayton@google.com>
- eee9f88ba21b182d7eb23bbc85af17f69185e34a tint: Extract intrinsic-table common type to helper by Ben Clayton <bclayton@google.com>
- 1b35e3f9a8c10c11d750fde76f0862e8e9bc9534 tint: Add new sem::Type helpers by Ben Clayton <bclayton@google.com>
- e5a67ac891a5c8aa584b7998d35453a29b778a93 tint: Remove ast::CallExpression -> sem::Call implicit ma... by Ben Clayton <bclayton@google.com>
- 7b921fb4c778b324d706f78a91d5e047626f2292 tint: No-op Resolver refactoring by Ben Clayton <bclayton@google.com>
- 86a617f1108cbfa49c8c1faebc7b4af8acd36588 Add InsertBraces: true to .clang-format by Austin Eng <enga@chromium.org>
- 2081ee43bf51005e2dbed2b271254d517e998fd0 tint: Add sem::Materialize by Ben Clayton <bclayton@google.com>
- 6ac00ed0c0cff0401da91b4faad649d0ea81f2d5 tint: IntrinsicTable: Add abstract numeric types by Ben Clayton <bclayton@google.com>
- b1fa457ab3c362a12bd885254352fc617d89f808 tint: IntrinsicTable: Use [[display]] name for type match... by Ben Clayton <bclayton@google.com>
- b0664684cd887f8c8163e70b64c797852b86e276 tint: Support tuples in utils::Hash(). by Ben Clayton <bclayton@google.com>
- 7f2b8cd8fc8edf464602ea64d2145def40fa3475 tint: Refactor Extensions / Enables. by Ben Clayton <bclayton@google.com>
- 23696b1ba3fd523f9f989677890af18db0d68d7a tint: Implement abstract-numeric overload resolution by Ben Clayton <bclayton@google.com>
- 2e681052b313ed547189d95d58d73081c028d604 tint: Fix use-after-free by Antonio Maiorano <amaiorano@google.com>
- c670018aea9f3ff989699b47c0b5d5a977213cc8 tint: intrinsics.def Support [[precedence]] decoration by Ben Clayton <bclayton@google.com>
- 5ff7d67bf341af630c8945296155b77edc13ef81 tint: Validate that sampled texture type must be f32, i32... by Antonio Maiorano <amaiorano@google.com>
- e0ff664a7f0dee5ac9c3c19e48121b6cfca89c31 tint: Add sem::Type::ConversionRank() by Ben Clayton <bclayton@google.com>
- 4c9ed74b5e5bded47aa034026a6ea80b27dd666b tint: IntrinsicTable: Rename open/closed -> template by Ben Clayton <bclayton@google.com>
- aaa9ba30436bdb23a59b9eaa4e65f1808cba0dec tint: Simplify sem::Constant::Scalar by Ben Clayton <bclayton@google.com>
- 661e33ca185f766019bd27fedda57a354efed787 tint: Cleanup of IntrinsicTable by Ben Clayton <bclayton@google.com>
- 8ba6e1d6ecdd3f9438b5034d32b301152cb931f8 tint: limit expression depth to avoid stack overflow in b... by Antonio Maiorano <amaiorano@google.com>
- 5880ed164abb36f816bbea1a715ad7bc988c3648 tint: Fix edge for CallSiteRequiredToBeUniform by James Price <jrprice@google.com>
- 3b5edf143505f6b97f065e83de0d63f647fd3e50 tint: Add matrix identify and single-scalar ctors by Ben Clayton <bclayton@google.com>
- 6ae608cb03840d1f8b075289f4445f149ab33f0a tint: Add constructors and conversions to the intrinsic t... by Ben Clayton <bclayton@google.com>
- 9ff8abf34711e4e740b68c10fc0c90bbc441c7e5 tint: Fix clang chromium-style warnings treated as errors by Ben Clayton <bclayton@google.com>
- e6b6777c8e56b0940315b9fef97a13e021c61747 tint: Fix MSL generation of '&' and '|' with booleans by Ben Clayton <bclayton@google.com>
- 35f0fcaac0f6e0d0a56e8f5f7c00cd297256d518 tint/uniformity: Use non-recursive graph traversal by James Price <jrprice@google.com>
- a89ff5981bc0c17e980a5dbdb4f2da870ed79db0 tint: Show where control flow became non-uniform by James Price <jrprice@google.com>
- 1c75921db9c0095d7ab96c686f51efa2951b2f4f tint: fix translation of DP4a on HLSL by Jiawei Shao <jiawei.shao@intel.com>
- d8e77e2e73afd5bb2238ac322d7acbdd084ec410 tint: Prevent integer overflow in IntrinsicTable by Ben Clayton <bclayton@google.com>
- 83fc247d4bb9ab23616a697f272d69f29f44447f tint: correctly define user-defined literals by Antonio Maiorano <amaiorano@google.com>
- 59e23943f3b1442281208e879e6bc4c5f478ca91 tint: Minor IntrinsicTable cleanup by Ben Clayton <bclayton@google.com>
- 77473b469958b242509c9eb9271bbcf908e791de tint: Split tables for unary and binary operators by Ben Clayton <bclayton@google.com>
- 62bfd318aefae4b5a1f50813f90bf0b8b821849b tint: Implement `f16` keyword in Tint frontend by Zhaoming Jiang <zhaoming.jiang@intel.com>
- c4b380b8af94fe8b7a61ae8bd3f735f9d7a51380 tint: Generalize sem::Vector to allow 16bits subtype by Zhaoming Jiang <zhaoming.jiang@intel.com>
- ed6ff9c948005a23fb2d592c5ea069d778bca083 tint: Rename kNotAnExtenxion to kNoExtension by Zhaoming Jiang <zhaoming.jiang@intel.com>
- ab9757036bd6b2fe86c4e937db0524463ba0c0f8 tint: Implement DP4a on HLSL writer by Jiawei Shao <jiawei.shao@intel.com>
- 53547db1d4f045d93ee408b6a30da25eb88ef056 tint: Add missing source information for | and || by James Price <jrprice@google.com>
- 816148fe3291d3def83de76584cfe32af8572f49 tint: Add implicit CF_return->{last cf} edge by James Price <jrprice@google.com>
- cd55f15c98de761c6410e19670398c149aa96dbe tint/resolver: Fix chromium-style warning treated as error by Ben Clayton <bclayton@google.com>
- 7dd0ab791a59c89b628981f82f56b9ee3e8208b6 tint: Show the source of non-uniformity by James Price <jrprice@google.com>
- 9c03abfb554fd64adb66a9f11d7e84766cdc15b3 tint: Show the reason for a uniformity requirement by James Price <jrprice@google.com>
- 874b61f1badfe275c480d1dcb6d32b867391de73 tint/uniformity: Retain control flow graphs by James Price <jrprice@google.com>
- be656f7984a48e3c4e9a3c9dcc0ba7bbdc3da278 tint: Implement uniformity analaysis by James Price <jrprice@google.com>
- 8e68f0aad7c3994ddbd1914a48d82c43dd6e7e56 tint: Resolve empty loop continuing blocks by James Price <jrprice@google.com>
- 2cf32b13d7c294a7a3b4e87f9ab11aebbb519e81 tint: Make ScopeStack key type generic by James Price <jrprice@google.com>
- 791b4351d1860e1d447f182619e8bd1023dc47eb tint: Add transform to disable uniformity analysis by James Price <jrprice@google.com>
GitOrigin-RevId: 55c0c9d950edb4f45b2f94d5c3e4114fc30609e8
Change-Id: I584598c20d24d8cadb29f63b5e1f46aac06aebb2
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/89880
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@chromium.org>
Reviewed-by: Ben Clayton <bclayton@chromium.org>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 259a26b..fbf443c 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -226,8 +226,12 @@
"ast/enable.h",
"ast/expression.cc",
"ast/expression.h",
+ "ast/extension.cc",
+ "ast/extension.h",
"ast/external_texture.cc",
"ast/external_texture.h",
+ "ast/f16.cc",
+ "ast/f16.h",
"ast/f32.cc",
"ast/f32.h",
"ast/fallthrough_statement.cc",
@@ -342,7 +346,6 @@
"debug.h",
"demangler.cc",
"demangler.h",
- "number.h",
"diagnostic/diagnostic.cc",
"diagnostic/diagnostic.h",
"diagnostic/formatter.cc",
@@ -357,6 +360,7 @@
"inspector/resource_binding.h",
"inspector/scalar.cc",
"inspector/scalar.h",
+ "number.h",
"program.cc",
"program.h",
"program_builder.cc",
@@ -365,6 +369,8 @@
"program_id.h",
"reader/reader.cc",
"reader/reader.h",
+ "resolver/ctor_conv_intrinsic.cc",
+ "resolver/ctor_conv_intrinsic.h",
"resolver/dependency_graph.cc",
"resolver/dependency_graph.h",
"resolver/intrinsic_table.cc",
@@ -375,9 +381,14 @@
"resolver/resolver_constants.cc",
"resolver/sem_helper.cc",
"resolver/sem_helper.h",
+ "resolver/uniformity.cc",
+ "resolver/uniformity.h",
"resolver/validator.cc",
"resolver/validator.h",
"scope_stack.h",
+ "sem/abstract_float.h",
+ "sem/abstract_int.h",
+ "sem/abstract_numeric.h",
"sem/array.h",
"sem/atomic.h",
"sem/behavior.h",
@@ -392,6 +403,7 @@
"sem/depth_texture.h",
"sem/expression.h",
"sem/external_texture.h",
+ "sem/f16.h",
"sem/f32.h",
"sem/for_loop_statement.h",
"sem/i32.h",
@@ -451,6 +463,8 @@
"transform/decompose_strided_array.h",
"transform/decompose_strided_matrix.cc",
"transform/decompose_strided_matrix.h",
+ "transform/disable_uniformity_analysis.cc",
+ "transform/disable_uniformity_analysis.h",
"transform/expand_compound_assignment.cc",
"transform/expand_compound_assignment.h",
"transform/first_index_offset.cc",
@@ -587,6 +601,8 @@
"sem/expression.h",
"sem/external_texture.cc",
"sem/external_texture.h",
+ "sem/f16.cc",
+ "sem/f16.h",
"sem/f32.cc",
"sem/f32.h",
"sem/for_loop_statement.cc",
@@ -600,6 +616,8 @@
"sem/info.h",
"sem/loop_statement.cc",
"sem/loop_statement.h",
+ "sem/materialize.cc",
+ "sem/materialize.h",
"sem/matrix.cc",
"sem/matrix.h",
"sem/member_accessor_expression.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 682817f..85ec3db 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -114,8 +114,12 @@
ast/enable.h
ast/expression.cc
ast/expression.h
+ ast/extension.cc
+ ast/extension.h
ast/external_texture.cc
ast/external_texture.h
+ ast/f16.cc
+ ast/f16.h
ast/f32.cc
ast/f32.h
ast/fallthrough_statement.cc
@@ -246,6 +250,8 @@
program.h
reader/reader.cc
reader/reader.h
+ resolver/ctor_conv_intrinsic.cc
+ resolver/ctor_conv_intrinsic.h
resolver/dependency_graph.cc
resolver/dependency_graph.h
resolver/intrinsic_table.cc
@@ -256,6 +262,8 @@
resolver/resolver.h
resolver/sem_helper.cc
resolver/sem_helper.h
+ resolver/uniformity.cc
+ resolver/uniformity.h
resolver/validator.cc
resolver/validator.h
scope_stack.h
@@ -333,6 +341,8 @@
transform/decompose_strided_array.h
transform/decompose_strided_matrix.cc
transform/decompose_strided_matrix.h
+ transform/disable_uniformity_analysis.cc
+ transform/disable_uniformity_analysis.h
transform/first_index_offset.cc
transform/first_index_offset.h
transform/fold_constants.cc
@@ -399,6 +409,8 @@
sem/depth_texture.h
sem/external_texture.cc
sem/external_texture.h
+ sem/f16.cc
+ sem/f16.h
sem/f32.cc
sem/f32.h
sem/for_loop_statement.cc
@@ -409,6 +421,8 @@
sem/if_statement.h
sem/loop_statement.cc
sem/loop_statement.h
+ sem/materialize.cc
+ sem/materialize.h
sem/matrix.cc
sem/matrix.h
sem/multisampled_texture.cc
@@ -681,7 +695,9 @@
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
@@ -785,7 +801,9 @@
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
@@ -798,6 +816,7 @@
sem/sem_struct_test.cc
sem/storage_texture_test.cc
sem/texture_test.cc
+ sem/type_test.cc
sem/type_manager_test.cc
sem/u32_test.cc
sem/vector_test.cc
@@ -831,6 +850,13 @@
writer/text_generator_test.cc
)
+ # Uniformity analysis tests depend on WGSL reader
+ if(${TINT_BUILD_WGSL_READER})
+ list(APPEND TINT_TEST_SRCS
+ resolver/uniformity_test.cc
+ )
+ endif()
+
# Inspector tests depend on WGSL reader
if(${TINT_BUILD_WGSL_READER})
list(APPEND TINT_TEST_SRCS
@@ -1044,6 +1070,7 @@
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_constants_test.cc
diff --git a/src/tint/ast/enable.cc b/src/tint/ast/enable.cc
index 857e110..ef43200 100644
--- a/src/tint/ast/enable.cc
+++ b/src/tint/ast/enable.cc
@@ -21,37 +21,7 @@
namespace tint::ast {
-Enable::ExtensionKind Enable::NameToKind(const std::string& name) {
- if (name == "chromium_experimental_dp4a") {
- return Enable::ExtensionKind::kChromiumExperimentalDP4a;
- }
-
- // The reserved internal extension name for testing
- if (name == "InternalExtensionForTesting") {
- return Enable::ExtensionKind::kInternalExtensionForTesting;
- }
-
- return Enable::ExtensionKind::kNotAnExtension;
-}
-
-std::string Enable::KindToName(ExtensionKind kind) {
- switch (kind) {
- case ExtensionKind::kChromiumExperimentalDP4a:
- return "chromium_experimental_dp4a";
- // The reserved internal extension for testing
- case ExtensionKind::kInternalExtensionForTesting:
- return "InternalExtensionForTesting";
- case ExtensionKind::kNotAnExtension:
- // Return an empty string for kNotAnExtension
- return {};
- // No default case, as this switch must cover all ExtensionKind values.
- }
- // This return shall never get hit.
- return {};
-}
-
-Enable::Enable(ProgramID pid, const Source& src, const std::string& ext_name)
- : Base(pid, src), name(ext_name), kind(NameToKind(ext_name)) {}
+Enable::Enable(ProgramID pid, const Source& src, Extension ext) : Base(pid, src), extension(ext) {}
Enable::Enable(Enable&&) = default;
@@ -59,6 +29,6 @@
const Enable* Enable::Clone(CloneContext* ctx) const {
auto src = ctx->Clone(source);
- return ctx->dst->create<Enable>(src, name);
+ return ctx->dst->create<Enable>(src, extension);
}
} // namespace tint::ast
diff --git a/src/tint/ast/enable.h b/src/tint/ast/enable.h
index 7bcd20e..674d9cb 100644
--- a/src/tint/ast/enable.h
+++ b/src/tint/ast/enable.h
@@ -16,57 +16,26 @@
#define SRC_TINT_AST_ENABLE_H_
#include <string>
-#include <unordered_set>
#include <utility>
+#include <vector>
-#include "src/tint/ast/access.h"
-#include "src/tint/ast/expression.h"
+#include "src/tint/ast/extension.h"
+#include "src/tint/ast/node.h"
namespace tint::ast {
-/// An instance of this class represents one extension mentioned in a
-/// "enable" derictive. Example:
-/// // Enable an extension named "f16"
-/// enable f16;
-class Enable : public Castable<Enable, Node> {
+/// An "enable" directive. Example:
+/// ```
+/// // Enable an extension named "f16"
+/// enable f16;
+/// ```
+class Enable final : public Castable<Enable, Node> {
public:
- /// The enum class identifing each supported WGSL extension
- enum class ExtensionKind {
- /// An extension for the experimental feature
- /// "chromium_experimental_dp4a".
- /// See crbug.com/tint/1497 for more details
- kChromiumExperimentalDP4a,
-
- /// An internal reserved extension for test, named
- /// "InternalExtensionForTesting"
- kInternalExtensionForTesting = -2,
- kNotAnExtension = -1,
- };
-
- /// Convert a string of extension name into one of ExtensionKind enum value,
- /// the result will be ExtensionKind::kNotAnExtension if the name is not a
- /// known extension name. A extension node of kind kNotAnExtension must not
- /// exist in the AST tree, and using a unknown extension name in WGSL code
- /// should result in a shader-creation error.
- /// @param name string of the extension name
- /// @return the ExtensionKind enum value for the extension of given name, or
- /// kNotAnExtension if no known extension has the given name
- static ExtensionKind NameToKind(const std::string& name);
-
- /// Convert the ExtensionKind enum value to corresponding extension name
- /// string. If the given enum value is kNotAnExtension or don't have a known
- /// name, return an empty string instead.
- /// @param kind the ExtensionKind enum value
- /// @return string of the extension name corresponding to the given kind, or
- /// an empty string if the given enum value is kNotAnExtension or don't have a
- /// known corresponding name
- static std::string KindToName(ExtensionKind kind);
-
/// Create a extension
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
- /// @param name the name of extension
- Enable(ProgramID pid, const Source& src, const std::string& name);
+ /// @param ext the extension
+ Enable(ProgramID pid, const Source& src, Extension ext);
/// Move constructor
Enable(Enable&&);
@@ -79,14 +48,11 @@
const Enable* Clone(CloneContext* ctx) const override;
/// The extension name
- const std::string name;
-
- /// The extension kind
- const ExtensionKind kind;
+ const Extension extension;
};
-/// A set of extension kinds
-using ExtensionSet = std::unordered_set<Enable::ExtensionKind>;
+/// A list of enables
+using EnableList = std::vector<const Enable*>;
} // namespace tint::ast
diff --git a/src/tint/ast/enable_test.cc b/src/tint/ast/enable_test.cc
index 9fde780..e8b6e5c 100644
--- a/src/tint/ast/enable_test.cc
+++ b/src/tint/ast/enable_test.cc
@@ -19,40 +19,15 @@
namespace tint::ast {
namespace {
-using AstExtensionTest = TestHelper;
+using EnableTest = TestHelper;
-TEST_F(AstExtensionTest, Creation) {
- auto* ext =
- create<Enable>(Source{Source::Range{Source::Location{20, 2}, Source::Location{20, 5}}},
- "InternalExtensionForTesting");
+TEST_F(EnableTest, Creation) {
+ auto* ext = create<ast::Enable>(Source{{{20, 2}, {20, 5}}}, Extension::kF16);
EXPECT_EQ(ext->source.range.begin.line, 20u);
EXPECT_EQ(ext->source.range.begin.column, 2u);
EXPECT_EQ(ext->source.range.end.line, 20u);
EXPECT_EQ(ext->source.range.end.column, 5u);
- EXPECT_EQ(ext->kind, ast::Enable::ExtensionKind::kInternalExtensionForTesting);
-}
-
-TEST_F(AstExtensionTest, Creation_InvalidName) {
- auto* ext = create<Enable>(
- Source{Source::Range{Source::Location{20, 2}, Source::Location{20, 5}}}, std::string());
- EXPECT_EQ(ext->source.range.begin.line, 20u);
- EXPECT_EQ(ext->source.range.begin.column, 2u);
- EXPECT_EQ(ext->source.range.end.line, 20u);
- EXPECT_EQ(ext->source.range.end.column, 5u);
- EXPECT_EQ(ext->kind, ast::Enable::ExtensionKind::kNotAnExtension);
-}
-
-TEST_F(AstExtensionTest, NameToKind_InvalidName) {
- EXPECT_EQ(ast::Enable::NameToKind(std::string()), ast::Enable::ExtensionKind::kNotAnExtension);
- EXPECT_EQ(ast::Enable::NameToKind("__ImpossibleExtensionName"),
- ast::Enable::ExtensionKind::kNotAnExtension);
- EXPECT_EQ(ast::Enable::NameToKind("123"), ast::Enable::ExtensionKind::kNotAnExtension);
-}
-
-TEST_F(AstExtensionTest, KindToName) {
- EXPECT_EQ(ast::Enable::KindToName(ast::Enable::ExtensionKind::kInternalExtensionForTesting),
- "InternalExtensionForTesting");
- EXPECT_EQ(ast::Enable::KindToName(ast::Enable::ExtensionKind::kNotAnExtension), std::string());
+ EXPECT_EQ(ext->extension, Extension::kF16);
}
} // namespace
diff --git a/src/tint/ast/extension.cc b/src/tint/ast/extension.cc
new file mode 100644
index 0000000..f03e3a0
--- /dev/null
+++ b/src/tint/ast/extension.cc
@@ -0,0 +1,51 @@
+// 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/extension.h"
+
+namespace tint::ast {
+
+Extension ParseExtension(const std::string& name) {
+ if (name == "chromium_experimental_dp4a") {
+ return Extension::kChromiumExperimentalDP4a;
+ }
+ if (name == "chromium_disable_uniformity_analysis") {
+ return Extension::kChromiumDisableUniformityAnalysis;
+ }
+ if (name == "f16") {
+ return Extension::kF16;
+ }
+ return Extension::kNone;
+}
+
+const char* str(Extension ext) {
+ switch (ext) {
+ case Extension::kChromiumExperimentalDP4a:
+ return "chromium_experimental_dp4a";
+ case Extension::kChromiumDisableUniformityAnalysis:
+ return "chromium_disable_uniformity_analysis";
+ case Extension::kF16:
+ return "f16";
+ case Extension::kNone:
+ return "<none>";
+ }
+ return "<unknown>";
+}
+
+std::ostream& operator<<(std::ostream& out, Extension i) {
+ out << str(i);
+ return out;
+}
+
+} // namespace tint::ast
diff --git a/src/tint/ast/extension.h b/src/tint/ast/extension.h
new file mode 100644
index 0000000..21e9ac1
--- /dev/null
+++ b/src/tint/ast/extension.h
@@ -0,0 +1,68 @@
+// 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_EXTENSION_H_
+#define SRC_TINT_AST_EXTENSION_H_
+
+#include <sstream>
+#include <string>
+
+#include "src/tint/utils/unique_vector.h"
+
+namespace tint::ast {
+
+/// An enumerator of WGSL extensions
+enum class Extension {
+ /// WGSL Extension "f16"
+ kF16,
+
+ /// An extension for the experimental feature
+ /// "chromium_experimental_dp4a".
+ /// See crbug.com/tint/1497 for more details
+ kChromiumExperimentalDP4a,
+ /// A Chromium-specific extension for disabling uniformity analysis.
+ kChromiumDisableUniformityAnalysis,
+
+ /// Reserved for representing "No extension required" or "Not a valid extension".
+ kNone,
+};
+
+/// Convert a string of extension name into one of Extension enum value, the result will be
+/// Extension::kNone if the name is not a known extension name. A extension node of kind
+/// kNone must not exist in the AST tree, and using a unknown extension name in WGSL code
+/// should result in a shader-creation error.
+/// @param name string of the extension name
+/// @return the Extension enum value for the extension of given name, or kNone if no known extension
+/// has the given name
+Extension ParseExtension(const std::string& name);
+
+/// Convert the Extension enum value to corresponding extension name string.
+/// @param ext the Extension enum value
+/// @return string of the extension name corresponding to the given kind, or
+/// an empty string if the given enum value is kNone or don't have a
+/// known corresponding name
+const char* ExtensionName(Extension ext);
+
+/// @returns the name of the extension.
+const char* str(Extension i);
+
+/// Emits the name of the extension type.
+std::ostream& operator<<(std::ostream& out, Extension i);
+
+// A unique vector of extensions
+using Extensions = utils::UniqueVector<Extension>;
+
+} // namespace tint::ast
+
+#endif // SRC_TINT_AST_EXTENSION_H_
diff --git a/src/tint/ast/extension_test.cc b/src/tint/ast/extension_test.cc
new file mode 100644
index 0000000..ed27674
--- /dev/null
+++ b/src/tint/ast/extension_test.cc
@@ -0,0 +1,36 @@
+
+// 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/ast/extension.h"
+
+#include "gtest/gtest.h"
+
+namespace tint::ast {
+namespace {
+
+TEST(ExtensionTest, NameToKind_InvalidName) {
+ EXPECT_EQ(ParseExtension("f16"), Extension::kF16);
+ EXPECT_EQ(ParseExtension(""), Extension::kNone);
+ EXPECT_EQ(ParseExtension("__ImpossibleExtensionName"), Extension::kNone);
+ EXPECT_EQ(ParseExtension("123"), Extension::kNone);
+}
+
+TEST(ExtensionTest, KindToName) {
+ EXPECT_EQ(std::string(str(Extension::kF16)), "f16");
+ EXPECT_EQ(std::string(str(Extension::kNone)), "<none>");
+}
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/f16.cc b/src/tint/ast/f16.cc
new file mode 100644
index 0000000..0eb1be5
--- /dev/null
+++ b/src/tint/ast/f16.cc
@@ -0,0 +1,38 @@
+// 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/f16.h"
+
+#include "src/tint/program_builder.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::ast::F16);
+
+namespace tint::ast {
+
+F16::F16(ProgramID pid, const Source& src) : Base(pid, src) {}
+
+F16::F16(F16&&) = default;
+
+F16::~F16() = default;
+
+std::string F16::FriendlyName(const SymbolTable&) const {
+ return "f16";
+}
+
+const F16* F16::Clone(CloneContext* ctx) const {
+ auto src = ctx->Clone(source);
+ return ctx->dst->create<F16>(src);
+}
+
+} // namespace tint::ast
diff --git a/src/tint/ast/f16.h b/src/tint/ast/f16.h
new file mode 100644
index 0000000..1b84f09
--- /dev/null
+++ b/src/tint/ast/f16.h
@@ -0,0 +1,48 @@
+// 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_F16_H_
+#define SRC_TINT_AST_F16_H_
+
+#include <string>
+
+#include "src/tint/ast/type.h"
+
+namespace tint::ast {
+
+/// A float 16 type
+class F16 : public Castable<F16, Type> {
+ public:
+ /// Constructor
+ /// @param pid the identifier of the program that owns this node
+ /// @param src the source of this node
+ F16(ProgramID pid, const Source& src);
+ /// Move constructor
+ F16(F16&&);
+ ~F16() override;
+
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
+ /// Clones this type and all transitive types using the `CloneContext` `ctx`.
+ /// @param ctx the clone context
+ /// @return the newly cloned type
+ const F16* Clone(CloneContext* ctx) const override;
+};
+
+} // namespace tint::ast
+
+#endif // SRC_TINT_AST_F16_H_
diff --git a/src/tint/ast/f16_test.cc b/src/tint/ast/f16_test.cc
new file mode 100644
index 0000000..48ab284
--- /dev/null
+++ b/src/tint/ast/f16_test.cc
@@ -0,0 +1,30 @@
+// 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/f16.h"
+
+#include "src/tint/ast/test_helper.h"
+
+namespace tint::ast {
+namespace {
+
+using AstF16Test = TestHelper;
+
+TEST_F(AstF16Test, FriendlyName) {
+ auto* f = create<F16>();
+ EXPECT_EQ(f->FriendlyName(Symbols()), "f16");
+}
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/float_literal_expression.h b/src/tint/ast/float_literal_expression.h
index 321efc891..72a395f 100644
--- a/src/tint/ast/float_literal_expression.h
+++ b/src/tint/ast/float_literal_expression.h
@@ -30,6 +30,8 @@
kNone,
/// 'f' suffix (f32)
kF,
+ /// 'h' suffix (f16)
+ kH,
};
/// Constructor
diff --git a/src/tint/ast/module.cc b/src/tint/ast/module.cc
index e163c19..40dff98 100644
--- a/src/tint/ast/module.cc
+++ b/src/tint/ast/module.cc
@@ -68,18 +68,18 @@
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
global_variables_.push_back(var);
},
- [&](const Enable* ext) {
- TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, ext, program_id);
- extensions_.insert(ext->kind);
+ [&](const Enable* enable) {
+ TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
+ enables_.push_back(enable);
},
[&](Default) { TINT_ICE(AST, diags) << "Unknown global declaration type"; });
}
-void Module::AddEnable(const ast::Enable* ext) {
- TINT_ASSERT(AST, ext);
- TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, ext, program_id);
- global_declarations_.push_back(ext);
- extensions_.insert(ext->kind);
+void Module::AddEnable(const ast::Enable* enable) {
+ TINT_ASSERT(AST, enable);
+ TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
+ global_declarations_.push_back(enable);
+ enables_.push_back(enable);
}
void Module::AddGlobalVariable(const ast::Variable* var) {
@@ -117,7 +117,7 @@
type_decls_.clear();
functions_.clear();
global_variables_.clear();
- extensions_.clear();
+ enables_.clear();
for (auto* decl : global_declarations_) {
if (!decl) {
diff --git a/src/tint/ast/module.h b/src/tint/ast/module.h
index d8be2ed..45b1ec6 100644
--- a/src/tint/ast/module.h
+++ b/src/tint/ast/module.h
@@ -78,7 +78,7 @@
VariableList& GlobalVariables() { return global_variables_; }
/// @returns the extension set for the module
- const ExtensionSet& Extensions() const { return extensions_; }
+ const EnableList& Enables() const { return enables_; }
/// Adds a type declaration to the Builder.
/// @param decl the type declaration to add
@@ -120,7 +120,7 @@
std::vector<const TypeDecl*> type_decls_;
FunctionList functions_;
VariableList global_variables_;
- ExtensionSet extensions_;
+ EnableList enables_;
};
} // namespace tint::ast
diff --git a/src/tint/ast/traverse_expressions.h b/src/tint/ast/traverse_expressions.h
index 650273b..59b00e9 100644
--- a/src/tint/ast/traverse_expressions.h
+++ b/src/tint/ast/traverse_expressions.h
@@ -54,40 +54,59 @@
/// @param root the root expression node
/// @param diags the diagnostics used for error messages
/// @param callback the callback function. Must be of the signature:
-/// `TraverseAction(const T*)` where T is an ast::Expression type.
+/// `TraverseAction(const T* expr)` or `TraverseAction(const T* expr, size_t depth)` where T
+/// is an ast::Expression type.
/// @return true on success, false on error
template <TraverseOrder ORDER = TraverseOrder::LeftToRight, typename CALLBACK>
bool TraverseExpressions(const ast::Expression* root, diag::List& diags, CALLBACK&& callback) {
using EXPR_TYPE = std::remove_pointer_t<traits::ParameterType<CALLBACK, 0>>;
- std::vector<const ast::Expression*> to_visit{root};
+ constexpr static bool kHasDepthArg = traits::SignatureOfT<CALLBACK>::parameter_count == 2;
- auto push_pair = [&](const ast::Expression* left, const ast::Expression* right) {
+ struct Pending {
+ const ast::Expression* expr;
+ size_t depth;
+ };
+
+ std::vector<Pending> to_visit{{root, 0}};
+
+ auto push_single = [&](const ast::Expression* expr, size_t depth) {
+ to_visit.push_back({expr, depth});
+ };
+ auto push_pair = [&](const ast::Expression* left, const ast::Expression* right, size_t depth) {
if (ORDER == TraverseOrder::LeftToRight) {
- to_visit.push_back(right);
- to_visit.push_back(left);
+ to_visit.push_back({right, depth});
+ to_visit.push_back({left, depth});
} else {
- to_visit.push_back(left);
- to_visit.push_back(right);
+ to_visit.push_back({left, depth});
+ to_visit.push_back({right, depth});
}
};
- auto push_list = [&](const std::vector<const ast::Expression*>& exprs) {
+ auto push_list = [&](const std::vector<const ast::Expression*>& exprs, size_t depth) {
if (ORDER == TraverseOrder::LeftToRight) {
for (auto* expr : utils::Reverse(exprs)) {
- to_visit.push_back(expr);
+ to_visit.push_back({expr, depth});
}
} else {
for (auto* expr : exprs) {
- to_visit.push_back(expr);
+ to_visit.push_back({expr, depth});
}
}
};
while (!to_visit.empty()) {
- auto* expr = to_visit.back();
+ auto p = to_visit.back();
to_visit.pop_back();
+ const ast::Expression* expr = p.expr;
- if (auto* filtered = expr->As<EXPR_TYPE>()) {
- switch (callback(filtered)) {
+ if (auto* filtered = expr->template As<EXPR_TYPE>()) {
+ TraverseAction result;
+ if constexpr (kHasDepthArg) {
+ result = callback(filtered, p.depth);
+ } else {
+ result = callback(filtered);
+ }
+
+ switch (result) {
case TraverseAction::Stop:
return true;
case TraverseAction::Skip:
@@ -100,32 +119,31 @@
bool ok = Switch(
expr,
[&](const IndexAccessorExpression* idx) {
- push_pair(idx->object, idx->index);
+ push_pair(idx->object, idx->index, p.depth + 1);
return true;
},
[&](const BinaryExpression* bin_op) {
- push_pair(bin_op->lhs, bin_op->rhs);
+ push_pair(bin_op->lhs, bin_op->rhs, p.depth + 1);
return true;
},
[&](const BitcastExpression* bitcast) {
- to_visit.push_back(bitcast->expr);
+ push_single(bitcast->expr, p.depth + 1);
return true;
},
[&](const CallExpression* call) {
// TODO(crbug.com/tint/1257): Resolver breaks if we actually include
- // the function name in the traversal. to_visit.push_back(call->func);
- push_list(call->args);
+ // the function name in the traversal. push_single(call->func);
+ push_list(call->args, p.depth + 1);
return true;
},
[&](const MemberAccessorExpression* member) {
// TODO(crbug.com/tint/1257): Resolver breaks if we actually include
- // the member name in the traversal. push_pair(member->structure,
- // member->member);
- to_visit.push_back(member->structure);
+ // the member name in the traversal. push_pair(member->member, p.depth + 1);
+ push_single(member->structure, p.depth + 1);
return true;
},
[&](const UnaryOpExpression* unary) {
- to_visit.push_back(unary->expr);
+ push_single(unary->expr, p.depth + 1);
return true;
},
[&](Default) {
diff --git a/src/tint/ast/traverse_expressions_test.cc b/src/tint/ast/traverse_expressions_test.cc
index 622a7ff..e79decb 100644
--- a/src/tint/ast/traverse_expressions_test.cc
+++ b/src/tint/ast/traverse_expressions_test.cc
@@ -73,6 +73,23 @@
}
}
+TEST_F(TraverseExpressionsTest, Depth) {
+ std::vector<const ast::Expression*> e = {Expr(1_i), Expr(1_i), Expr(1_i), Expr(1_i)};
+ std::vector<const ast::Expression*> i = {Add(e[0], e[1]), Sub(e[2], e[3])};
+ auto* root = Mul(i[0], i[1]);
+
+ size_t j = 0;
+ size_t depths[] = {0, 1, 2, 2, 1, 2, 2};
+ {
+ TraverseExpressions<TraverseOrder::LeftToRight>( //
+ root, Diagnostics(), [&](const ast::Expression* expr, size_t depth) {
+ (void)expr;
+ EXPECT_THAT(depth, depths[j++]);
+ return ast::TraverseAction::Descend;
+ });
+ }
+}
+
TEST_F(TraverseExpressionsTest, DescendBitcastExpression) {
auto* e = Expr(1_i);
auto* b0 = Bitcast<i32>(e);
diff --git a/src/tint/cmd/main.cc b/src/tint/cmd/main.cc
index 52dfd70..b9c6d04 100644
--- a/src/tint/cmd/main.cc
+++ b/src/tint/cmd/main.cc
@@ -125,30 +125,36 @@
(void)fmt;
#if TINT_BUILD_SPV_WRITER
- if (fmt == "spirv")
+ if (fmt == "spirv") {
return Format::kSpirv;
- if (fmt == "spvasm")
+ }
+ if (fmt == "spvasm") {
return Format::kSpvAsm;
+ }
#endif // TINT_BUILD_SPV_WRITER
#if TINT_BUILD_WGSL_WRITER
- if (fmt == "wgsl")
+ if (fmt == "wgsl") {
return Format::kWgsl;
+ }
#endif // TINT_BUILD_WGSL_WRITER
#if TINT_BUILD_MSL_WRITER
- if (fmt == "msl")
+ if (fmt == "msl") {
return Format::kMsl;
+ }
#endif // TINT_BUILD_MSL_WRITER
#if TINT_BUILD_HLSL_WRITER
- if (fmt == "hlsl")
+ if (fmt == "hlsl") {
return Format::kHlsl;
+ }
#endif // TINT_BUILD_HLSL_WRITER
#if TINT_BUILD_GLSL_WRITER
- if (fmt == "glsl")
+ if (fmt == "glsl") {
return Format::kGlsl;
+ }
#endif // TINT_BUILD_GLSL_WRITER
return Format::kNone;
diff --git a/src/tint/inspector/inspector.cc b/src/tint/inspector/inspector.cc
index 36fcfb7..569a104 100644
--- a/src/tint/inspector/inspector.cc
+++ b/src/tint/inspector/inspector.cc
@@ -19,6 +19,7 @@
#include "src/tint/ast/bool_literal_expression.h"
#include "src/tint/ast/call_expression.h"
+#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/interpolate_attribute.h"
@@ -27,10 +28,12 @@
#include "src/tint/sem/array.h"
#include "src/tint/sem/call.h"
#include "src/tint/sem/depth_multisampled_texture.h"
+#include "src/tint/sem/f16.h"
#include "src/tint/sem/f32.h"
#include "src/tint/sem/function.h"
#include "src/tint/sem/i32.h"
#include "src/tint/sem/matrix.h"
+#include "src/tint/sem/module.h"
#include "src/tint/sem/multisampled_texture.h"
#include "src/tint/sem/sampled_texture.h"
#include "src/tint/sem/statement.h"
@@ -543,16 +546,13 @@
}
std::vector<std::string> Inspector::GetUsedExtensionNames() {
- std::vector<std::string> result;
-
- ast::ExtensionSet set = program_->AST().Extensions();
- result.reserve(set.size());
- for (auto kind : set) {
- std::string name = ast::Enable::KindToName(kind);
- result.push_back(name);
+ auto& extensions = program_->Sem().Module()->Extensions();
+ std::vector<std::string> out;
+ out.reserve(extensions.size());
+ for (auto ext : extensions) {
+ out.push_back(ast::str(ext));
}
-
- return result;
+ return out;
}
std::vector<std::pair<std::string, Source>> Inspector::GetEnableDirectives() {
@@ -562,7 +562,7 @@
auto global_decls = program_->AST().GlobalDeclarations();
for (auto* node : global_decls) {
if (auto* ext = node->As<ast::Enable>()) {
- result.push_back({ext->name, ext->source});
+ result.push_back({ast::str(ext->extension), ext->source});
}
}
@@ -777,7 +777,7 @@
continue;
}
- auto* call = sem.Get(c);
+ auto* call = sem.Get(c)->UnwrapMaterialize()->As<sem::Call>();
if (!call) {
continue;
}
diff --git a/src/tint/inspector/inspector_test.cc b/src/tint/inspector/inspector_test.cc
index 18a33b1..033f5b8 100644
--- a/src/tint/inspector/inspector_test.cc
+++ b/src/tint/inspector/inspector_test.cc
@@ -2849,7 +2849,7 @@
// Test calling GetUsedExtensionNames on a shader with valid extension.
TEST_F(InspectorGetUsedExtensionNamesTest, Simple) {
std::string shader = R"(
-enable InternalExtensionForTesting;
+enable f16;
@stage(fragment)
fn main() {
@@ -2859,15 +2859,15 @@
auto result = inspector.GetUsedExtensionNames();
EXPECT_EQ(result.size(), 1u);
- EXPECT_EQ(result[0], "InternalExtensionForTesting");
+ EXPECT_EQ(result[0], "f16");
}
// Test calling GetUsedExtensionNames on a shader with a extension enabled for
// multiple times.
TEST_F(InspectorGetUsedExtensionNamesTest, Duplicated) {
std::string shader = R"(
-enable InternalExtensionForTesting;
-enable InternalExtensionForTesting;
+enable f16;
+enable f16;
@stage(fragment)
fn main() {
@@ -2877,7 +2877,7 @@
auto result = inspector.GetUsedExtensionNames();
EXPECT_EQ(result.size(), 1u);
- EXPECT_EQ(result[0], "InternalExtensionForTesting");
+ EXPECT_EQ(result[0], "f16");
}
// Test calling GetEnableDirectives on a empty shader.
@@ -2906,7 +2906,7 @@
// Test calling GetEnableDirectives on a shader with valid extension.
TEST_F(InspectorGetEnableDirectivesTest, Simple) {
std::string shader = R"(
-enable InternalExtensionForTesting;
+enable f16;
@stage(fragment)
fn main() {
@@ -2916,17 +2916,17 @@
auto result = inspector.GetEnableDirectives();
EXPECT_EQ(result.size(), 1u);
- EXPECT_EQ(result[0].first, "InternalExtensionForTesting");
- EXPECT_EQ(result[0].second.range, (Source::Range{{2, 8}, {2, 35}}));
+ EXPECT_EQ(result[0].first, "f16");
+ EXPECT_EQ(result[0].second.range, (Source::Range{{2, 8}, {2, 11}}));
}
// Test calling GetEnableDirectives on a shader with a extension enabled for
// multiple times.
TEST_F(InspectorGetEnableDirectivesTest, Duplicated) {
std::string shader = R"(
-enable InternalExtensionForTesting;
+enable f16;
-enable InternalExtensionForTesting;
+enable f16;
@stage(fragment)
fn main() {
})";
@@ -2935,10 +2935,10 @@
auto result = inspector.GetEnableDirectives();
EXPECT_EQ(result.size(), 2u);
- EXPECT_EQ(result[0].first, "InternalExtensionForTesting");
- EXPECT_EQ(result[0].second.range, (Source::Range{{2, 8}, {2, 35}}));
- EXPECT_EQ(result[1].first, "InternalExtensionForTesting");
- EXPECT_EQ(result[1].second.range, (Source::Range{{4, 8}, {4, 35}}));
+ EXPECT_EQ(result[0].first, "f16");
+ EXPECT_EQ(result[0].second.range, (Source::Range{{2, 8}, {2, 11}}));
+ EXPECT_EQ(result[1].first, "f16");
+ EXPECT_EQ(result[1].second.range, (Source::Range{{4, 8}, {4, 11}}));
}
// Crash was occuring in ::GenerateSamplerTargets, when
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index 0bebe4b..bc4bf28 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -62,16 +62,32 @@
////////////////////////////////////////////////////////////////////////////////
// WGSL primitive types //
+// Types may be decorated with [[precedence(N)]] to prioritize which type //
+// will be picked when multiple types of a matcher match. //
+// This is used to ensure that abstract numerical types materialize to the //
+// concrete type with the lowest conversion rank. //
+// Types with higher the precedence values will be matched first. //
////////////////////////////////////////////////////////////////////////////////
// https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section
type bool
-type f32
-type i32
-type u32
+[[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
type vec2<T>
type vec3<T>
type vec4<T>
+type mat2x2<T>
+type mat2x3<T>
+type mat2x4<T>
+type mat3x2<T>
+type mat3x3<T>
+type mat3x4<T>
+type mat4x2<T>
+type mat4x3<T>
+type mat4x4<T>
[[display("vec{N}<{T}>")]] type vec<N: num, T>
[[display("mat{N}x{M}<{T}>")]] type mat<N: num, M: num, T>
type ptr<S: storage_class, T, A: access>
@@ -112,6 +128,12 @@
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 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
////////////////////////////////////////////////////////////////////////////////
// Enum matchers //
@@ -141,7 +163,7 @@
// functions supported by the WGSL language. This builtin definition //
// language supports simple static-type function declarations, as well as //
// single overload declarations that can match a number of different //
-// argument types via the use of 'open-types' and 'open-numbers'. //
+// argument types via the use of template types and template numbers //
// //
// * Basic example: //
// //
@@ -150,10 +172,9 @@
// Declares an overload of the function 'isInf' that accepts a single //
// parameter of type 'f32' and returns a 'bool'. //
// //
-// An 'open-type' can be thought as a template type that is determined by the //
-// arguments to the builtin. //
+// A template type is a type determined by the arguments to the builtin. //
// //
-// * Open-type example without constraint: //
+// * Template type example without constraint: //
// //
// fn arrayLength<T>(array<T>) -> u32 //
// //
@@ -162,7 +183,7 @@
// element type. This overload will always return a value of the same type //
// as its single argument. //
// //
-// * Open-type example with constraint: //
+// * Template type example with constraint: //
// //
// fn abs<T: fiu32>(T) -> T //
// //
@@ -170,10 +191,10 @@
// argument of type 'f32', 'i32' or 'u32', which returns a value of the //
// same argument type. //
// //
-// Similarly an 'open-number' can be thought as a template number or //
-// enumerator that is determined by the arguments to the builtin. //
+// Similarly a template number is a number or enumerator that is determined //
+// by the arguments to the builtin. //
// //
-// * Open-number example: //
+// * Template number example: //
// //
// fn dpdx<N: num>(vec<N, f32>) -> vec<N, f32> //
// //
@@ -182,54 +203,76 @@
// the same argument type. //
// //
// //
-// Matching algorithm: //
-// ------------------- //
+// Matching algorithm for a single overload: //
+// ----------------------------------------- //
// //
-// Prior to matching an overload, all open-types are undefined. //
+// The goal of matching is to compare a function call's arguments in the //
+// program source against a possibly-templated overload declaration, and //
+// determine if the call satisfies the form and type constraints of the //
+// overload. Currently it is impossible for a call to match more than one //
+// overload definition. In the event that more than one overload matches, an //
+// ICE will be raised. Note that Tint may need to support multiple-overload //
+// resolution in the future, depending on future overload definitions. //
// //
-// Open-types become closed-types (pinned to a fixed type) on the first //
-// attempt to match an argument to that open-type. //
-// Once open-types are closed, they remain that type for the rest of the //
-// overload evaluation. //
+// Prior to matching an overload, all template types are undefined. //
+// //
+// Template types are first defined with the type of the leftmost argument //
+// that matches against that template type name. Subsequent arguments that //
+// attempt to match against the template type name will either reject the //
+// overload or refine the template, in one of 3 ways: //
+// (a) Fail to match, causing the overload to be immediately rejected. //
+// (b) Match the existing template type, either exactly or via implicit //
+// conversion, and overload resolution continues. //
+// (c) Match via implicit conversion of the currently defined template type //
+// to the argument type. In this situation, the template type is refined //
+// with the more constrained argument type, and overload resolution //
+// continues. //
// //
// To better understand, let's consider the following hypothetical overload //
// declaration: //
// //
// fn foo<T: scalar>(T, T); //
// //
-// T - is the open-type //
+// T - is the template type name //
// scalar - is a matcher for the types 'f32', 'i32', 'u32' or 'bool' //
// (declared above) //
-// <T: scalar> - declares the open-type T, with the constraint that T must //
-// match one of 'f32', 'i32', 'u32' or 'bool'. //
+// <T: scalar> - declares the template type T, with the constraint that T //
+// must match one of 'f32', 'i32', 'u32' or 'bool'. //
// //
// The process for resolving this overload is as follows: //
// //
// (1) The overload resolver begins by attempting to match the argument //
// types from left to right. //
-// The first parameter type is compared against the argument type. //
-// As the open-type T has not been closed yet, T is closed as the type //
-// of the first argument. //
+// The first parameter type is compared against the argument type T. //
+// As the template type T has not been defined yet, T is defined as the //
+// type of the first argument. //
// There's no verification that the T type is a scalar at this stage. //
// (2) The second parameter is then compared against the second argument. //
-// As the open-type T is now closed, the argument type is compared //
-// against the value of the closed-type of T. If the types match, then //
-// the overload is still a candidate for matching, otherwise the //
-// overload is no longer considered. //
-// (3) If all the parameters matched, constraints on the open-types need //
-// to be checked next. If the closed-type does not match the 'match' //
-// constraint, then the overload is no longer considered. //
+// As the template type T is now defined the argument type is compared //
+// against the value of the defined type of T. Depending on the //
+// comparison of the argument type to the template type, either the //
+// actions of (a), (b) or (c) from above will occur. //
+// (3) If all the parameters matched, constraints on the template types //
+// need to be checked next. If the defined type does not match the //
+// 'match' constraint, then the overload is no longer considered. //
// //
-// The algorithm for matching open-numbers is almost identical to open-types, //
-// except of course, they match against integer numbers or enumerators //
-// instead of types. //
+// This algorithm is less general than the overload resolution described in //
+// the WGSL spec. But it makes the same decisions because the overloads //
+// defined by WGSL are monotonic in the sense that once a template parameter //
+// has been refined, there is never a need to backtrack and un-refine it to //
+// match a later argument. //
+// //
+// The algorithm for matching template numbers is similar to matching //
+// template types, except numbers need to exactly match across all uses - //
+// there is no implicit conversion. Template numbers may match integer //
+// numbers or enumerators. //
// //
// //
// * More examples: //
// //
// fn F() //
// - Function called F. //
-// No open types or numbers, no parameters, no return value //
+// No template types or numbers, no parameters, no return value //
// //
// fn F() -> RETURN_TYPE //
// - Function with RETURN_TYPE as the return type value //
@@ -243,21 +286,21 @@
// some builtin functions //
// //
// fn F<T>(T) //
-// - Single parameter of unconstrained open-type T (any type) //
+// - Single parameter of unconstrained template type T (any type) //
// //
// fn F<T: scalar>(T) //
-// - Single parameter of constrained open-type T (must be a scalar) //
+// - Single parameter of constrained template type T (must be a scalar) //
// //
// fn F<T: fiu32>(T) -> T //
-// - Single parameter of constrained open-type T (must be a one of fiu32) //
-// Return type matches parameter type //
+// - Single parameter of constrained template type T (must be a one of //
+// fiu32) Return type matches parameter type //
// //
// fn F<T, N: num>(vec<N, T>) //
-// - Single parameter of vector type with open-number size N and element //
-// open-type T //
+// - Single parameter of vector type with template number size N and //
+// element template type T //
// //
// fn F<A: access>(texture_storage_1d<f32_texel_format, A>) //
-// - Single parameter of texture_storage_1d type with open-number //
+// - Single parameter of texture_storage_1d type with template number //
// access-control C, and of a texel format that is listed in //
// f32_texel_format //
// //
@@ -563,6 +606,140 @@
[[stage("fragment", "compute")]] fn atomicCompareExchangeWeak<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> vec2<T>
////////////////////////////////////////////////////////////////////////////////
+// Type constructors //
+////////////////////////////////////////////////////////////////////////////////
+
+// Zero value constructors
+ctor i32() -> i32
+ctor u32() -> u32
+ctor f32() -> f32
+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>
+
+// Identity constructors
+ctor i32(i32) -> i32
+ctor u32(u32) -> u32
+ctor f32(f32) -> f32
+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>
+
+// Vector constructors
+ctor vec2<T: abstract_or_scalar>(T) -> vec2<T>
+ctor vec2<T: abstract_or_scalar>(x: T, y: T) -> vec2<T>
+ctor vec3<T: abstract_or_scalar>(T) -> vec3<T>
+ctor vec3<T: abstract_or_scalar>(x: T, y: T, z: T) -> vec3<T>
+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>
+ctor vec4<T: abstract_or_scalar>(T) -> vec4<T>
+ctor vec4<T: abstract_or_scalar>(x: T, y: T, z: T, w: T) -> vec4<T>
+ctor vec4<T: abstract_or_scalar>(xy: vec2<T>, z: T, w: T) -> vec4<T>
+ctor vec4<T: abstract_or_scalar>(x: T, yz: vec2<T>, w: T) -> vec4<T>
+ctor vec4<T: abstract_or_scalar>(x: T, y: T, zw: vec2<T>) -> vec4<T>
+ctor vec4<T: abstract_or_scalar>(xy: vec2<T>, zw: vec2<T>) -> vec4<T>
+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>
+
+// 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>
+
+////////////////////////////////////////////////////////////////////////////////
+// Type conversions //
+////////////////////////////////////////////////////////////////////////////////
+conv f32<T: scalar_no_f32>(T) -> f32
+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: 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: 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: 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>
+
+////////////////////////////////////////////////////////////////////////////////
// Operators //
// //
// The operator declarations below declare all the unary and binary operators //
diff --git a/src/tint/number.h b/src/tint/number.h
index a4bd369..c3be236 100644
--- a/src/tint/number.h
+++ b/src/tint/number.h
@@ -18,6 +18,12 @@
#include <stdint.h>
#include <functional>
+namespace tint::detail {
+/// An empty structure used as a unique template type for Number when
+/// specializing for the f16 type.
+struct NumberKindF16 {};
+} // namespace tint::detail
+
namespace tint {
/// Number wraps a integer or floating point number, enforcing explicit casting.
@@ -72,6 +78,43 @@
return Number<A>(a) == b;
}
+/// The partial specification of Number for f16 type, storing the f16 value as float,
+/// and enforcing proper explicit casting.
+template <>
+struct Number<detail::NumberKindF16> {
+ /// Constructor. The value is zero-initialized.
+ Number() = default;
+
+ /// Constructor.
+ /// @param v the value to initialize this Number to
+ template <typename U>
+ explicit Number(U v) : value(static_cast<float>(v)) {}
+
+ /// Constructor.
+ /// @param v the value to initialize this Number to
+ template <typename U>
+ explicit Number(Number<U> v) : value(static_cast<float>(v.value)) {}
+
+ /// Conversion operator
+ /// @returns the value as the internal representation type of F16
+ operator float() const { return value; }
+
+ /// Negation operator
+ /// @returns the negative value of the number
+ Number operator-() const { return Number<detail::NumberKindF16>(-value); }
+
+ /// Assignment operator with parameter as native floating point type
+ /// @param v the new value
+ /// @returns this Number so calls can be chained
+ Number& operator=(float v) {
+ value = v;
+ return *this;
+ }
+
+ /// The number value, stored as float
+ float value = {};
+};
+
/// `AInt` is a type alias to `Number<int64_t>`.
using AInt = Number<int64_t>;
/// `AFloat` is a type alias to `Number<double>`.
@@ -83,41 +126,54 @@
using u32 = Number<uint32_t>;
/// `f32` is a type alias to `Number<float>`
using f32 = Number<float>;
+/// `f16` is a type alias to `Number<detail::NumberKindF16>`, which should be IEEE 754 binary16.
+/// However since C++ don't have native binary16 type, the value is stored as float.
+using f16 = Number<detail::NumberKindF16>;
} // namespace tint
namespace tint::number_suffixes {
/// Literal suffix for abstract integer literals
-inline AInt operator"" _a(unsigned long long int value) { // NOLINT
+inline AInt operator""_a(unsigned long long int value) { // NOLINT
return AInt(static_cast<int64_t>(value));
}
/// Literal suffix for abstract float literals
-inline AFloat operator"" _a(long double value) { // NOLINT
+inline AFloat operator""_a(long double value) { // NOLINT
return AFloat(static_cast<double>(value));
}
/// Literal suffix for i32 literals
-inline i32 operator"" _i(unsigned long long int value) { // NOLINT
+inline i32 operator""_i(unsigned long long int value) { // NOLINT
return i32(static_cast<int32_t>(value));
}
/// Literal suffix for u32 literals
-inline u32 operator"" _u(unsigned long long int value) { // NOLINT
+inline u32 operator""_u(unsigned long long int value) { // NOLINT
return u32(static_cast<uint32_t>(value));
}
/// Literal suffix for f32 literals
-inline f32 operator"" _f(long double value) { // NOLINT
+inline f32 operator""_f(long double value) { // NOLINT
return f32(static_cast<double>(value));
}
/// Literal suffix for f32 literals
-inline f32 operator"" _f(unsigned long long int value) { // NOLINT
+inline f32 operator""_f(unsigned long long int value) { // NOLINT
return f32(static_cast<double>(value));
}
+/// Literal suffix for f16 literals
+inline f16 operator""_h(long double value) { // NOLINT
+ return f16(static_cast<double>(value));
+}
+
+/// Literal suffix for f16 literals
+inline f16 operator""_h(unsigned long long int value) { // NOLINT
+ return f16(static_cast<double>(value));
+}
+
} // namespace tint::number_suffixes
#endif // SRC_TINT_NUMBER_H_
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index 7dd2c81..38970a5 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -39,7 +39,9 @@
#include "src/tint/ast/disable_validation_attribute.h"
#include "src/tint/ast/discard_statement.h"
#include "src/tint/ast/enable.h"
+#include "src/tint/ast/extension.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/float_literal_expression.h"
@@ -82,6 +84,7 @@
#include "src/tint/sem/bool.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/i32.h"
#include "src/tint/sem/matrix.h"
@@ -385,6 +388,15 @@
return builder->create<ast::Bool>(source);
}
+ /// @returns a f16 type
+ const ast::F16* f16() const { return builder->create<ast::F16>(); }
+
+ /// @param source the Source of the node
+ /// @returns a f16 type
+ const ast::F16* f16(const Source& source) const {
+ return builder->create<ast::F16>(source);
+ }
+
/// @returns a f32 type
const ast::F32* f32() const { return builder->create<ast::F32>(); }
@@ -1005,6 +1017,21 @@
}
/// @param source the source information
+ /// @param value the float value
+ /// @return a 'h'-suffixed FloatLiteralExpression for the f16 value
+ const ast::FloatLiteralExpression* Expr(const Source& source, f16 value) {
+ return create<ast::FloatLiteralExpression>(source, static_cast<double>(value.value),
+ ast::FloatLiteralExpression::Suffix::kH);
+ }
+
+ /// @param value the float value
+ /// @return a 'h'-suffixed FloatLiteralExpression for the f16 value
+ const ast::FloatLiteralExpression* Expr(f16 value) {
+ return create<ast::FloatLiteralExpression>(static_cast<double>(value.value),
+ ast::FloatLiteralExpression::Suffix::kH);
+ }
+
+ /// @param source the source information
/// @param value the integer value
/// @return an unsuffixed IntLiteralExpression for the AInt value
const ast::IntLiteralExpression* Expr(const Source& source, AInt value) {
@@ -1281,6 +1308,15 @@
return Construct(ty.array(subtype, std::forward<EXPR>(n)), std::forward<ARGS>(args)...);
}
+ /// Adds the extension to the list of enable directives at the top of the module.
+ /// @param ext the extension to enable
+ /// @return an `ast::Enable` enabling the given extension.
+ const ast::Enable* Enable(ast::Extension ext) {
+ auto* enable = create<ast::Enable>(ext);
+ AST().AddEnable(enable);
+ return enable;
+ }
+
/// @param name the variable name
/// @param type the variable type
/// @param optional the optional variable settings.
@@ -2600,6 +2636,25 @@
/// the type declaration has no resolved type.
const sem::Type* TypeOf(const ast::TypeDecl* type_decl) const;
+ /// @param type a type
+ /// @returns the name for `type` that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const ast::Type* type) {
+ return type ? type->FriendlyName(Symbols()) : "<null>";
+ }
+
+ /// @param type a type
+ /// @returns the name for `type` that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const sem::Type* type) {
+ return type ? type->FriendlyName(Symbols()) : "<null>";
+ }
+
+ /// Overload of FriendlyName, which removes an ambiguity when passing nullptr.
+ /// Simplifies test code.
+ /// @returns "<null>"
+ std::string FriendlyName(std::nullptr_t) { return "<null>"; }
+
/// Wraps the ast::Expression in a statement. This is used by tests that
/// construct a partial AST and require the Resolver to reach these
/// nodes.
@@ -2675,6 +2730,10 @@
static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) { return t->f32(); }
};
template <>
+struct ProgramBuilder::TypesBuilder::CToAST<f16> {
+ static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) { return t->f16(); }
+};
+template <>
struct ProgramBuilder::TypesBuilder::CToAST<bool> {
static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) { return t->bool_(); }
};
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index 82f6224..d88773e 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -602,10 +602,12 @@
// header, we will visit its merge block, then its continue target (if any).
// Also records the post order ordering.
void VisitBackward(uint32_t id) {
- if (id == 0)
+ if (id == 0) {
return;
- if (visited_.count(id))
+ }
+ if (visited_.count(id)) {
return;
+ }
visited_.insert(id);
const spvtools::opt::BasicBlock* bb = id_to_block_[id]; // non-null for valid modules
@@ -1600,8 +1602,9 @@
bool is_single_block_loop = false;
block_info->basic_block->ForEachSuccessorLabel(
[&is_single_block_loop, block_id](const uint32_t succ) {
- if (block_id == succ)
+ if (block_id == succ) {
is_single_block_loop = true;
+ }
});
const auto ct = block_info->continue_for_header;
block_info->is_continue_entire_loop = ct == block_id;
diff --git a/src/tint/reader/spirv/parser_impl_barrier_test.cc b/src/tint/reader/spirv/parser_impl_barrier_test.cc
index 0549bd1..fdfa3bf 100644
--- a/src/tint/reader/spirv/parser_impl_barrier_test.cc
+++ b/src/tint/reader/spirv/parser_impl_barrier_test.cc
@@ -69,7 +69,7 @@
auto* call = helper->body->statements[0]->As<ast::CallStatement>();
ASSERT_NE(call, nullptr);
EXPECT_EQ(call->expr->args.size(), 0u);
- auto* sem_call = program.Sem().Get(call->expr);
+ auto* sem_call = program.Sem().Get<sem::Call>(call->expr);
ASSERT_NE(sem_call, nullptr);
auto* builtin = sem_call->Target()->As<sem::Builtin>();
ASSERT_NE(builtin, nullptr);
@@ -102,7 +102,7 @@
auto* call = helper->body->statements[0]->As<ast::CallStatement>();
ASSERT_NE(call, nullptr);
EXPECT_EQ(call->expr->args.size(), 0u);
- auto* sem_call = program.Sem().Get(call->expr);
+ auto* sem_call = program.Sem().Get<sem::Call>(call->expr);
ASSERT_NE(sem_call, nullptr);
auto* builtin = sem_call->Target()->As<sem::Builtin>();
ASSERT_NE(builtin, nullptr);
diff --git a/src/tint/reader/wgsl/lexer.cc b/src/tint/reader/wgsl/lexer.cc
index db75613..20b3364 100644
--- a/src/tint/reader/wgsl/lexer.cc
+++ b/src/tint/reader/wgsl/lexer.cc
@@ -232,8 +232,9 @@
}
bool Lexer::matches(size_t pos, std::string_view sub_string) {
- if (pos >= length())
+ if (pos >= length()) {
return false;
+ }
return substr(pos, sub_string.size()) == sub_string;
}
@@ -265,8 +266,9 @@
// If the cursor didn't advance we didn't remove any blankspace
// so we're done.
- if (loc == location_)
+ if (loc == location_) {
break;
+ }
}
if (is_eof()) {
return {Token::Type::kEOF, begin_source()};
@@ -1043,108 +1045,159 @@
}
Token Lexer::check_keyword(const Source& source, std::string_view str) {
- if (str == "array")
+ if (str == "array") {
return {Token::Type::kArray, source, "array"};
- if (str == "atomic")
+ }
+ if (str == "atomic") {
return {Token::Type::kAtomic, source, "atomic"};
- if (str == "bitcast")
+ }
+ if (str == "bitcast") {
return {Token::Type::kBitcast, source, "bitcast"};
- if (str == "bool")
+ }
+ if (str == "bool") {
return {Token::Type::kBool, source, "bool"};
- if (str == "break")
+ }
+ if (str == "break") {
return {Token::Type::kBreak, source, "break"};
- if (str == "case")
+ }
+ if (str == "case") {
return {Token::Type::kCase, source, "case"};
- if (str == "continue")
+ }
+ if (str == "continue") {
return {Token::Type::kContinue, source, "continue"};
- if (str == "continuing")
+ }
+ if (str == "continuing") {
return {Token::Type::kContinuing, source, "continuing"};
- if (str == "discard")
+ }
+ if (str == "discard") {
return {Token::Type::kDiscard, source, "discard"};
- if (str == "default")
+ }
+ if (str == "default") {
return {Token::Type::kDefault, source, "default"};
- if (str == "else")
+ }
+ if (str == "else") {
return {Token::Type::kElse, source, "else"};
- if (str == "enable")
+ }
+ if (str == "enable") {
return {Token::Type::kEnable, source, "enable"};
- if (str == "f32")
+ }
+ if (str == "f16") {
+ return {Token::Type::kF16, source, "f16"};
+ }
+ if (str == "f32") {
return {Token::Type::kF32, source, "f32"};
- if (str == "fallthrough")
+ }
+ if (str == "fallthrough") {
return {Token::Type::kFallthrough, source, "fallthrough"};
- if (str == "false")
+ }
+ if (str == "false") {
return {Token::Type::kFalse, source, "false"};
- if (str == "fn")
+ }
+ if (str == "fn") {
return {Token::Type::kFn, source, "fn"};
- if (str == "for")
+ }
+ if (str == "for") {
return {Token::Type::kFor, source, "for"};
- if (str == "function")
+ }
+ if (str == "function") {
return {Token::Type::kFunction, source, "function"};
- if (str == "i32")
+ }
+ if (str == "i32") {
return {Token::Type::kI32, source, "i32"};
- if (str == "if")
+ }
+ if (str == "if") {
return {Token::Type::kIf, source, "if"};
- if (str == "import")
+ }
+ if (str == "import") {
return {Token::Type::kImport, source, "import"};
- if (str == "let")
+ }
+ if (str == "let") {
return {Token::Type::kLet, source, "let"};
- if (str == "loop")
+ }
+ if (str == "loop") {
return {Token::Type::kLoop, source, "loop"};
- if (str == "mat2x2")
+ }
+ if (str == "mat2x2") {
return {Token::Type::kMat2x2, source, "mat2x2"};
- if (str == "mat2x3")
+ }
+ if (str == "mat2x3") {
return {Token::Type::kMat2x3, source, "mat2x3"};
- if (str == "mat2x4")
+ }
+ if (str == "mat2x4") {
return {Token::Type::kMat2x4, source, "mat2x4"};
- if (str == "mat3x2")
+ }
+ if (str == "mat3x2") {
return {Token::Type::kMat3x2, source, "mat3x2"};
- if (str == "mat3x3")
+ }
+ if (str == "mat3x3") {
return {Token::Type::kMat3x3, source, "mat3x3"};
- if (str == "mat3x4")
+ }
+ if (str == "mat3x4") {
return {Token::Type::kMat3x4, source, "mat3x4"};
- if (str == "mat4x2")
+ }
+ if (str == "mat4x2") {
return {Token::Type::kMat4x2, source, "mat4x2"};
- if (str == "mat4x3")
+ }
+ if (str == "mat4x3") {
return {Token::Type::kMat4x3, source, "mat4x3"};
- if (str == "mat4x4")
+ }
+ if (str == "mat4x4") {
return {Token::Type::kMat4x4, source, "mat4x4"};
- if (str == "override")
+ }
+ if (str == "override") {
return {Token::Type::kOverride, source, "override"};
- if (str == "private")
+ }
+ if (str == "private") {
return {Token::Type::kPrivate, source, "private"};
- if (str == "ptr")
+ }
+ if (str == "ptr") {
return {Token::Type::kPtr, source, "ptr"};
- if (str == "return")
+ }
+ if (str == "return") {
return {Token::Type::kReturn, source, "return"};
- if (str == "sampler")
+ }
+ if (str == "sampler") {
return {Token::Type::kSampler, source, "sampler"};
- if (str == "sampler_comparison")
+ }
+ if (str == "sampler_comparison") {
return {Token::Type::kComparisonSampler, source, "sampler_comparison"};
- if (str == "storage_buffer" || str == "storage")
+ }
+ if (str == "storage_buffer" || str == "storage") {
return {Token::Type::kStorage, source, "storage"};
- if (str == "struct")
+ }
+ if (str == "struct") {
return {Token::Type::kStruct, source, "struct"};
- if (str == "switch")
+ }
+ if (str == "switch") {
return {Token::Type::kSwitch, source, "switch"};
- if (str == "texture_1d")
+ }
+ if (str == "texture_1d") {
return {Token::Type::kTextureSampled1d, source, "texture_1d"};
- if (str == "texture_2d")
+ }
+ if (str == "texture_2d") {
return {Token::Type::kTextureSampled2d, source, "texture_2d"};
- if (str == "texture_2d_array")
+ }
+ if (str == "texture_2d_array") {
return {Token::Type::kTextureSampled2dArray, source, "texture_2d_array"};
- if (str == "texture_3d")
+ }
+ if (str == "texture_3d") {
return {Token::Type::kTextureSampled3d, source, "texture_3d"};
- if (str == "texture_cube")
+ }
+ if (str == "texture_cube") {
return {Token::Type::kTextureSampledCube, source, "texture_cube"};
+ }
if (str == "texture_cube_array") {
return {Token::Type::kTextureSampledCubeArray, source, "texture_cube_array"};
}
- if (str == "texture_depth_2d")
+ if (str == "texture_depth_2d") {
return {Token::Type::kTextureDepth2d, source, "texture_depth_2d"};
+ }
if (str == "texture_depth_2d_array") {
return {Token::Type::kTextureDepth2dArray, source, "texture_depth_2d_array"};
}
- if (str == "texture_depth_cube")
+ if (str == "texture_depth_cube") {
return {Token::Type::kTextureDepthCube, source, "texture_depth_cube"};
+ }
if (str == "texture_depth_cube_array") {
return {Token::Type::kTextureDepthCubeArray, source, "texture_depth_cube_array"};
}
@@ -1169,24 +1222,33 @@
if (str == "texture_storage_3d") {
return {Token::Type::kTextureStorage3d, source, "texture_storage_3d"};
}
- if (str == "true")
+ if (str == "true") {
return {Token::Type::kTrue, source, "true"};
- if (str == "type")
+ }
+ if (str == "type") {
return {Token::Type::kType, source, "type"};
- if (str == "u32")
+ }
+ if (str == "u32") {
return {Token::Type::kU32, source, "u32"};
- if (str == "uniform")
+ }
+ if (str == "uniform") {
return {Token::Type::kUniform, source, "uniform"};
- if (str == "var")
+ }
+ if (str == "var") {
return {Token::Type::kVar, source, "var"};
- if (str == "vec2")
+ }
+ if (str == "vec2") {
return {Token::Type::kVec2, source, "vec2"};
- if (str == "vec3")
+ }
+ if (str == "vec3") {
return {Token::Type::kVec3, source, "vec3"};
- if (str == "vec4")
+ }
+ if (str == "vec4") {
return {Token::Type::kVec4, source, "vec4"};
- if (str == "workgroup")
+ }
+ if (str == "workgroup") {
return {Token::Type::kWorkgroup, source, "workgroup"};
+ }
return {};
}
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index b2b9a03..4ad0f76 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -124,8 +124,8 @@
// 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 == "f16" ||
- t == "f64" || t == "handle" || t == "i8" || t == "i16" || t == "i64" || t == "mat" ||
+ 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";
}
@@ -141,18 +141,24 @@
/// @return the current enter-exit depth for the given block token type. If
/// `t` is not a block token type, then 0 is always returned.
int consume(const Token& t) {
- if (t.Is(Token::Type::kBraceLeft))
+ if (t.Is(Token::Type::kBraceLeft)) {
return brace++;
- if (t.Is(Token::Type::kBraceRight))
+ }
+ if (t.Is(Token::Type::kBraceRight)) {
return brace--;
- if (t.Is(Token::Type::kBracketLeft))
+ }
+ if (t.Is(Token::Type::kBracketLeft)) {
return bracket++;
- if (t.Is(Token::Type::kBracketRight))
+ }
+ if (t.Is(Token::Type::kBracketRight)) {
return bracket--;
- if (t.Is(Token::Type::kParenLeft))
+ }
+ if (t.Is(Token::Type::kParenLeft)) {
return paren++;
- if (t.Is(Token::Type::kParenRight))
+ }
+ if (t.Is(Token::Type::kParenRight)) {
return paren--;
+ }
return 0;
}
};
@@ -310,6 +316,9 @@
if (after_global_decl) {
add_error(p, "enable directives must come before all global declarations");
}
+ } else if (ed.errored) {
+ // Found a invalid enable directive.
+ continue;
} else {
auto gd = global_decl();
@@ -345,6 +354,11 @@
synchronized_ = true;
next();
name = {t.to_str(), t.source()};
+ } else if (t.Is(Token::Type::kF16)) {
+ // `f16` is a valid extension name and also a keyword
+ synchronized_ = true;
+ next();
+ name = {"f16", t.source()};
} else if (handle_error(t)) {
// The token might itself be an error.
return Failure::kErrored;
@@ -358,13 +372,11 @@
return Failure::kErrored;
}
- if (ast::Enable::NameToKind(name.value) != ast::Enable::ExtensionKind::kNotAnExtension) {
- const ast::Enable* extension = create<ast::Enable>(name.source, name.value);
- builder_.AST().AddEnable(extension);
- } else {
- // Error if an unknown extension is used
+ auto extension = ast::ParseExtension(name.value);
+ if (extension == ast::Extension::kNone) {
return add_error(name.source, "unsupported extension: '" + name.value + "'");
}
+ builder_.AST().AddEnable(create<ast::Enable>(name.source, extension));
return true;
});
@@ -387,56 +399,66 @@
// | struct_decl
// | function_decl
Maybe<bool> ParserImpl::global_decl() {
- if (match(Token::Type::kSemicolon) || match(Token::Type::kEOF))
+ if (match(Token::Type::kSemicolon) || match(Token::Type::kEOF)) {
return true;
+ }
bool errored = false;
auto attrs = attribute_list();
- if (attrs.errored)
+ if (attrs.errored) {
errored = true;
- if (!continue_parsing())
+ }
+ if (!continue_parsing()) {
return Failure::kErrored;
+ }
auto decl = sync(Token::Type::kSemicolon, [&]() -> Maybe<bool> {
auto gv = global_variable_decl(attrs.value);
- if (gv.errored)
+ if (gv.errored) {
return Failure::kErrored;
+ }
if (gv.matched) {
- if (!expect("variable declaration", Token::Type::kSemicolon))
+ if (!expect("variable declaration", Token::Type::kSemicolon)) {
return Failure::kErrored;
+ }
builder_.AST().AddGlobalVariable(gv.value);
return true;
}
auto gc = global_constant_decl(attrs.value);
- if (gc.errored)
+ if (gc.errored) {
return Failure::kErrored;
+ }
if (gc.matched) {
- if (!expect("let declaration", Token::Type::kSemicolon))
+ if (!expect("let declaration", Token::Type::kSemicolon)) {
return Failure::kErrored;
+ }
builder_.AST().AddGlobalVariable(gc.value);
return true;
}
auto ta = type_alias();
- if (ta.errored)
+ if (ta.errored) {
return Failure::kErrored;
+ }
if (ta.matched) {
- if (!expect("type alias", Token::Type::kSemicolon))
+ if (!expect("type alias", Token::Type::kSemicolon)) {
return Failure::kErrored;
+ }
builder_.AST().AddTypeDecl(ta.value);
return true;
}
auto str = struct_decl();
- if (str.errored)
+ if (str.errored) {
return Failure::kErrored;
+ }
if (str.matched) {
builder_.AST().AddTypeDecl(str.value);
@@ -504,16 +526,19 @@
// | variable_attribute_list* variable_decl EQUAL const_expr
Maybe<const ast::Variable*> ParserImpl::global_variable_decl(ast::AttributeList& attrs) {
auto decl = variable_decl();
- if (decl.errored)
+ if (decl.errored) {
return Failure::kErrored;
- if (!decl.matched)
+ }
+ if (!decl.matched) {
return Failure::kNoMatch;
+ }
const ast::Expression* constructor = nullptr;
if (match(Token::Type::kEqual)) {
auto expr = expect_const_expr();
- if (expr.errored)
+ if (expr.errored) {
return Failure::kErrored;
+ }
constructor = expr.value;
}
@@ -546,8 +571,9 @@
}
auto decl = expect_variable_ident_decl(use, /* allow_inferred = */ true);
- if (decl.errored)
+ if (decl.errored) {
return Failure::kErrored;
+ }
const ast::Expression* initializer = nullptr;
if (match(Token::Type::kEqual)) {
@@ -573,20 +599,23 @@
// : VAR variable_qualifier? variable_ident_decl
Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl(bool allow_inferred) {
Source source;
- if (!match(Token::Type::kVar, &source))
+ if (!match(Token::Type::kVar, &source)) {
return Failure::kNoMatch;
+ }
VariableQualifier vq;
auto explicit_vq = variable_qualifier();
- if (explicit_vq.errored)
+ if (explicit_vq.errored) {
return Failure::kErrored;
+ }
if (explicit_vq.matched) {
vq = explicit_vq.value;
}
auto decl = expect_variable_ident_decl("variable declaration", allow_inferred);
- if (decl.errored)
+ if (decl.errored) {
return Failure::kErrored;
+ }
return VarDeclInfo{decl->source, decl->name, vq.storage_class, vq.access, decl->type};
}
@@ -600,16 +629,19 @@
// COMMA access GREATER_THAN
Maybe<const ast::Type*> ParserImpl::texture_samplers() {
auto type = sampler();
- if (type.matched)
+ if (type.matched) {
return type;
+ }
type = depth_texture();
- if (type.matched)
+ if (type.matched) {
return type;
+ }
type = external_texture();
- if (type.matched)
+ if (type.matched) {
return type.value;
+ }
auto source_range = make_source_range();
@@ -618,8 +650,9 @@
const char* use = "sampled texture type";
auto subtype = expect_lt_gt_block(use, [&] { return expect_type(use); });
- if (subtype.errored)
+ if (subtype.errored) {
return Failure::kErrored;
+ }
return builder_.ty.sampled_texture(source_range, dim.value, subtype.value);
}
@@ -629,8 +662,9 @@
const char* use = "multisampled texture type";
auto subtype = expect_lt_gt_block(use, [&] { return expect_type(use); });
- if (subtype.errored)
+ if (subtype.errored) {
return Failure::kErrored;
+ }
return builder_.ty.multisampled_texture(source_range, ms_dim.value, subtype.value);
}
@@ -673,11 +707,13 @@
// | SAMPLER_COMPARISON
Maybe<const ast::Type*> ParserImpl::sampler() {
Source source;
- if (match(Token::Type::kSampler, &source))
+ if (match(Token::Type::kSampler, &source)) {
return builder_.ty.sampler(source, ast::SamplerKind::kSampler);
+ }
- if (match(Token::Type::kComparisonSampler, &source))
+ if (match(Token::Type::kComparisonSampler, &source)) {
return builder_.ty.sampler(source, ast::SamplerKind::kComparisonSampler);
+ }
return Failure::kNoMatch;
}
@@ -690,23 +726,29 @@
// | TEXTURE_SAMPLED_CUBE
// | TEXTURE_SAMPLED_CUBE_ARRAY
Maybe<const ast::TextureDimension> ParserImpl::sampled_texture() {
- if (match(Token::Type::kTextureSampled1d))
+ if (match(Token::Type::kTextureSampled1d)) {
return ast::TextureDimension::k1d;
+ }
- if (match(Token::Type::kTextureSampled2d))
+ if (match(Token::Type::kTextureSampled2d)) {
return ast::TextureDimension::k2d;
+ }
- if (match(Token::Type::kTextureSampled2dArray))
+ if (match(Token::Type::kTextureSampled2dArray)) {
return ast::TextureDimension::k2dArray;
+ }
- if (match(Token::Type::kTextureSampled3d))
+ if (match(Token::Type::kTextureSampled3d)) {
return ast::TextureDimension::k3d;
+ }
- if (match(Token::Type::kTextureSampledCube))
+ if (match(Token::Type::kTextureSampledCube)) {
return ast::TextureDimension::kCube;
+ }
- if (match(Token::Type::kTextureSampledCubeArray))
+ if (match(Token::Type::kTextureSampledCubeArray)) {
return ast::TextureDimension::kCubeArray;
+ }
return Failure::kNoMatch;
}
@@ -725,8 +767,9 @@
// multisampled_texture
// : TEXTURE_MULTISAMPLED_2D
Maybe<const ast::TextureDimension> ParserImpl::multisampled_texture() {
- if (match(Token::Type::kTextureMultisampled2d))
+ if (match(Token::Type::kTextureMultisampled2d)) {
return ast::TextureDimension::k2d;
+ }
return Failure::kNoMatch;
}
@@ -737,14 +780,18 @@
// | TEXTURE_STORAGE_2D_ARRAY
// | TEXTURE_STORAGE_3D
Maybe<const ast::TextureDimension> ParserImpl::storage_texture() {
- if (match(Token::Type::kTextureStorage1d))
+ if (match(Token::Type::kTextureStorage1d)) {
return ast::TextureDimension::k1d;
- if (match(Token::Type::kTextureStorage2d))
+ }
+ if (match(Token::Type::kTextureStorage2d)) {
return ast::TextureDimension::k2d;
- if (match(Token::Type::kTextureStorage2dArray))
+ }
+ if (match(Token::Type::kTextureStorage2dArray)) {
return ast::TextureDimension::k2dArray;
- if (match(Token::Type::kTextureStorage3d))
+ }
+ if (match(Token::Type::kTextureStorage3d)) {
return ast::TextureDimension::k3d;
+ }
return Failure::kNoMatch;
}
@@ -850,37 +897,45 @@
Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(std::string_view use,
bool allow_inferred) {
auto ident = expect_ident(use);
- if (ident.errored)
+ if (ident.errored) {
return Failure::kErrored;
+ }
if (allow_inferred && !peek_is(Token::Type::kColon)) {
return TypedIdentifier{nullptr, ident.value, ident.source};
}
- if (!expect(use, Token::Type::kColon))
+ if (!expect(use, Token::Type::kColon)) {
return Failure::kErrored;
+ }
auto t = peek();
auto type = type_decl();
- if (type.errored)
+ if (type.errored) {
return Failure::kErrored;
- if (!type.matched)
+ }
+ if (!type.matched) {
return add_error(t.source(), "invalid type", use);
+ }
return TypedIdentifier{type.value, ident.value, ident.source};
}
Expect<ast::Access> ParserImpl::expect_access(std::string_view use) {
auto ident = expect_ident(use);
- if (ident.errored)
+ if (ident.errored) {
return Failure::kErrored;
+ }
- if (ident.value == kReadAccess)
+ if (ident.value == kReadAccess) {
return {ast::Access::kRead, ident.source};
- if (ident.value == kWriteAccess)
+ }
+ if (ident.value == kWriteAccess) {
return {ast::Access::kWrite, ident.source};
- if (ident.value == kReadWriteAccess)
+ }
+ if (ident.value == kReadWriteAccess) {
return {ast::Access::kReadWrite, ident.source};
+ }
return add_error(ident.source, "invalid value for access control");
}
@@ -920,24 +975,29 @@
// type_alias
// : TYPE IDENT EQUAL type_decl
Maybe<const ast::Alias*> ParserImpl::type_alias() {
- if (!peek_is(Token::Type::kType))
+ if (!peek_is(Token::Type::kType)) {
return Failure::kNoMatch;
+ }
auto t = next();
const char* use = "type alias";
auto name = expect_ident(use);
- if (name.errored)
+ if (name.errored) {
return Failure::kErrored;
+ }
- if (!expect(use, Token::Type::kEqual))
+ if (!expect(use, Token::Type::kEqual)) {
return Failure::kErrored;
+ }
auto type = type_decl();
- if (type.errored)
+ if (type.errored) {
return Failure::kErrored;
- if (!type.matched)
+ }
+ if (!type.matched) {
return add_error(peek(), "invalid type alias");
+ }
return builder_.ty.alias(make_source_range_from(t.source()), name.value, type.value);
}
@@ -973,17 +1033,25 @@
return builder_.create<ast::TypeName>(source, builder_.Symbols().Register(t.to_str()));
}
- if (match(Token::Type::kBool, &source))
+ if (match(Token::Type::kBool, &source)) {
return builder_.ty.bool_(source);
+ }
- if (match(Token::Type::kF32, &source))
+ if (match(Token::Type::kF16, &source)) {
+ return builder_.ty.f16(source);
+ }
+
+ if (match(Token::Type::kF32, &source)) {
return builder_.ty.f32(source);
+ }
- if (match(Token::Type::kI32, &source))
+ if (match(Token::Type::kI32, &source)) {
return builder_.ty.i32(source);
+ }
- if (match(Token::Type::kU32, &source))
+ if (match(Token::Type::kU32, &source)) {
return builder_.ty.u32(source);
+ }
if (t.IsVector()) {
next(); // Consume the peek
@@ -1008,20 +1076,24 @@
}
auto texture_or_sampler = texture_samplers();
- if (texture_or_sampler.errored)
+ if (texture_or_sampler.errored) {
return Failure::kErrored;
- if (texture_or_sampler.matched)
+ }
+ if (texture_or_sampler.matched) {
return texture_or_sampler;
+ }
return Failure::kNoMatch;
}
Expect<const ast::Type*> ParserImpl::expect_type(std::string_view use) {
auto type = type_decl();
- if (type.errored)
+ if (type.errored) {
return Failure::kErrored;
- if (!type.matched)
+ }
+ if (!type.matched) {
return add_error(peek().source(), "invalid type", use);
+ }
return type.value;
}
@@ -1105,8 +1177,9 @@
auto subtype = expect_lt_gt_block(use, [&]() -> Expect<const ast::Type*> {
auto type = expect_type(use);
- if (type.errored)
+ if (type.errored) {
return Failure::kErrored;
+ }
if (match(Token::Type::kComma)) {
auto expr = primary_expression();
@@ -1167,20 +1240,25 @@
Expect<ast::StorageClass> ParserImpl::expect_storage_class(std::string_view use) {
auto source = peek().source();
- if (match(Token::Type::kUniform))
+ if (match(Token::Type::kUniform)) {
return {ast::StorageClass::kUniform, source};
+ }
- if (match(Token::Type::kWorkgroup))
+ if (match(Token::Type::kWorkgroup)) {
return {ast::StorageClass::kWorkgroup, source};
+ }
- if (match(Token::Type::kStorage))
+ if (match(Token::Type::kStorage)) {
return {ast::StorageClass::kStorage, source};
+ }
- if (match(Token::Type::kPrivate))
+ if (match(Token::Type::kPrivate)) {
return {ast::StorageClass::kPrivate, source};
+ }
- if (match(Token::Type::kFunction))
+ if (match(Token::Type::kFunction)) {
return {ast::StorageClass::kFunction, source};
+ }
return add_error(source, "invalid storage class", use);
}
@@ -1191,16 +1269,19 @@
auto t = peek();
auto source = t.source();
- if (!match(Token::Type::kStruct))
+ if (!match(Token::Type::kStruct)) {
return Failure::kNoMatch;
+ }
auto name = expect_ident("struct declaration");
- if (name.errored)
+ if (name.errored) {
return Failure::kErrored;
+ }
auto body = expect_struct_body_decl();
- if (body.errored)
+ if (body.errored) {
return Failure::kErrored;
+ }
auto sym = builder_.Symbols().Register(name.value);
return create<ast::Struct>(source, sym, std::move(body.value), ast::AttributeList{});
@@ -1235,8 +1316,9 @@
next();
continue;
}
- if (!match(Token::Type::kComma))
+ if (!match(Token::Type::kComma)) {
break;
+ }
}
if (errored) {
return Failure::kErrored;
@@ -1254,8 +1336,9 @@
}
auto decl = expect_variable_ident_decl("struct member");
- if (decl.errored)
+ if (decl.errored) {
return Failure::kErrored;
+ }
return create<ast::StructMember>(decl->source, builder_.Symbols().Register(decl->name),
decl->type, std::move(attrs.value));
@@ -1277,17 +1360,20 @@
}
return Failure::kErrored;
}
- if (!header.matched)
+ if (!header.matched) {
return Failure::kNoMatch;
+ }
bool errored = false;
auto body = expect_body_stmt();
- if (body.errored)
+ if (body.errored) {
errored = true;
+ }
- if (errored)
+ if (errored) {
return Failure::kErrored;
+ }
return create<ast::Function>(header->source, builder_.Symbols().Register(header->name),
header->params, header->return_type, body.value, attrs,
@@ -1367,12 +1453,14 @@
}
auto param = expect_param();
- if (param.errored)
+ if (param.errored) {
return Failure::kErrored;
+ }
ret.push_back(param.value);
- if (!match(Token::Type::kComma))
+ if (!match(Token::Type::kComma)) {
break;
+ }
}
return ret;
@@ -1384,8 +1472,9 @@
auto attrs = attribute_list();
auto decl = expect_variable_ident_decl("parameter");
- if (decl.errored)
+ if (decl.errored) {
return Failure::kErrored;
+ }
auto* var = create<ast::Variable>(decl->source, // source
builder_.Symbols().Register(decl->name), // symbol
@@ -1427,12 +1516,14 @@
Expect<ast::Builtin> ParserImpl::expect_builtin() {
auto ident = expect_ident("builtin");
- if (ident.errored)
+ if (ident.errored) {
return Failure::kErrored;
+ }
ast::Builtin builtin = ident_to_builtin(ident.value);
- if (builtin == ast::Builtin::kNone)
+ if (builtin == ast::Builtin::kNone) {
return add_error(ident.source, "invalid value for builtin attribute");
+ }
return {builtin, ident.source};
}
@@ -1442,8 +1533,9 @@
Expect<ast::BlockStatement*> ParserImpl::expect_body_stmt() {
return expect_brace_block("", [&]() -> Expect<ast::BlockStatement*> {
auto stmts = expect_statements();
- if (stmts.errored)
+ if (stmts.errored) {
return Failure::kErrored;
+ }
return create<ast::BlockStatement>(Source{}, stmts.value);
});
}
@@ -1453,10 +1545,12 @@
Expect<const ast::Expression*> ParserImpl::expect_paren_rhs_stmt() {
return expect_paren_block("", [&]() -> Expect<const ast::Expression*> {
auto expr = logical_or_expression();
- if (expr.errored)
+ if (expr.errored) {
return Failure::kErrored;
- if (!expr.matched)
+ }
+ if (!expr.matched) {
return add_error(peek(), "unable to parse expression");
+ }
return expr.value;
});
@@ -1479,8 +1573,9 @@
}
}
- if (errored)
+ if (errored) {
return Failure::kErrored;
+ }
return stmts;
}
@@ -1510,39 +1605,50 @@
// Non-block statments that error can resynchronize on semicolon.
auto stmt = sync(Token::Type::kSemicolon, [&] { return non_block_statement(); });
- if (stmt.errored)
+ if (stmt.errored) {
return Failure::kErrored;
- if (stmt.matched)
+ }
+ if (stmt.matched) {
return stmt;
+ }
auto stmt_if = if_stmt();
- if (stmt_if.errored)
+ if (stmt_if.errored) {
return Failure::kErrored;
- if (stmt_if.matched)
+ }
+ if (stmt_if.matched) {
return stmt_if.value;
+ }
auto sw = switch_stmt();
- if (sw.errored)
+ if (sw.errored) {
return Failure::kErrored;
- if (sw.matched)
+ }
+ if (sw.matched) {
return sw.value;
+ }
auto loop = loop_stmt();
- if (loop.errored)
+ if (loop.errored) {
return Failure::kErrored;
- if (loop.matched)
+ }
+ if (loop.matched) {
return loop.value;
+ }
auto stmt_for = for_stmt();
- if (stmt_for.errored)
+ if (stmt_for.errored) {
return Failure::kErrored;
- if (stmt_for.matched)
+ }
+ if (stmt_for.matched) {
return stmt_for.value;
+ }
if (peek_is(Token::Type::kBraceLeft)) {
auto body = expect_body_stmt();
- if (body.errored)
+ if (body.errored) {
return Failure::kErrored;
+ }
return body.value;
}
@@ -1562,50 +1668,64 @@
Maybe<const ast::Statement*> ParserImpl::non_block_statement() {
auto stmt = [&]() -> Maybe<const ast::Statement*> {
auto ret_stmt = return_stmt();
- if (ret_stmt.errored)
+ if (ret_stmt.errored) {
return Failure::kErrored;
- if (ret_stmt.matched)
+ }
+ if (ret_stmt.matched) {
return ret_stmt.value;
+ }
auto func = func_call_stmt();
- if (func.errored)
+ if (func.errored) {
return Failure::kErrored;
- if (func.matched)
+ }
+ if (func.matched) {
return func.value;
+ }
auto var = variable_stmt();
- if (var.errored)
+ if (var.errored) {
return Failure::kErrored;
- if (var.matched)
+ }
+ if (var.matched) {
return var.value;
+ }
auto b = break_stmt();
- if (b.errored)
+ if (b.errored) {
return Failure::kErrored;
- if (b.matched)
+ }
+ if (b.matched) {
return b.value;
+ }
auto cont = continue_stmt();
- if (cont.errored)
+ if (cont.errored) {
return Failure::kErrored;
- if (cont.matched)
+ }
+ if (cont.matched) {
return cont.value;
+ }
auto assign = assignment_stmt();
- if (assign.errored)
+ if (assign.errored) {
return Failure::kErrored;
- if (assign.matched)
+ }
+ if (assign.matched) {
return assign.value;
+ }
Source source;
- if (match(Token::Type::kDiscard, &source))
+ if (match(Token::Type::kDiscard, &source)) {
return create<ast::DiscardStatement>(source);
+ }
return Failure::kNoMatch;
}();
- if (stmt.matched && !expect(stmt->Name(), Token::Type::kSemicolon))
+ if (stmt.matched && !expect(stmt->Name(), Token::Type::kSemicolon)) {
return Failure::kErrored;
+ }
return stmt;
}
@@ -1614,15 +1734,18 @@
// : RETURN logical_or_expression?
Maybe<const ast::ReturnStatement*> ParserImpl::return_stmt() {
Source source;
- if (!match(Token::Type::kReturn, &source))
+ if (!match(Token::Type::kReturn, &source)) {
return Failure::kNoMatch;
+ }
- if (peek_is(Token::Type::kSemicolon))
+ if (peek_is(Token::Type::kSemicolon)) {
return create<ast::ReturnStatement>(source, nullptr);
+ }
auto expr = logical_or_expression();
- if (expr.errored)
+ if (expr.errored) {
return Failure::kErrored;
+ }
// TODO(bclayton): Check matched?
return create<ast::ReturnStatement>(source, expr.value);
@@ -1636,17 +1759,21 @@
if (match(Token::Type::kLet)) {
auto decl = expect_variable_ident_decl("let declaration",
/*allow_inferred = */ true);
- if (decl.errored)
+ if (decl.errored) {
return Failure::kErrored;
+ }
- if (!expect("let declaration", Token::Type::kEqual))
+ if (!expect("let declaration", Token::Type::kEqual)) {
return Failure::kErrored;
+ }
auto constructor = logical_or_expression();
- if (constructor.errored)
+ if (constructor.errored) {
return Failure::kErrored;
- if (!constructor.matched)
+ }
+ if (!constructor.matched) {
return add_error(peek(), "missing constructor for let declaration");
+ }
auto* var = create<ast::Variable>(decl->source, // source
builder_.Symbols().Register(decl->name), // symbol
@@ -1662,18 +1789,22 @@
}
auto decl = variable_decl(/*allow_inferred = */ true);
- if (decl.errored)
+ if (decl.errored) {
return Failure::kErrored;
- if (!decl.matched)
+ }
+ if (!decl.matched) {
return Failure::kNoMatch;
+ }
const ast::Expression* constructor = nullptr;
if (match(Token::Type::kEqual)) {
auto constructor_expr = logical_or_expression();
- if (constructor_expr.errored)
+ if (constructor_expr.errored) {
return Failure::kErrored;
- if (!constructor_expr.matched)
+ }
+ if (!constructor_expr.matched) {
return add_error(peek(), "missing constructor for variable declaration");
+ }
constructor = constructor_expr.value;
}
@@ -1777,12 +1908,14 @@
// : SWITCH paren_rhs_stmt BRACKET_LEFT switch_body+ BRACKET_RIGHT
Maybe<const ast::SwitchStatement*> ParserImpl::switch_stmt() {
Source source;
- if (!match(Token::Type::kSwitch, &source))
+ if (!match(Token::Type::kSwitch, &source)) {
return Failure::kNoMatch;
+ }
auto condition = logical_or_expression();
- if (condition.errored)
+ if (condition.errored) {
return Failure::kErrored;
+ }
if (!condition.matched) {
return add_error(peek(), "unable to parse selector expression");
}
@@ -1796,17 +1929,20 @@
errored = true;
continue;
}
- if (!stmt.matched)
+ if (!stmt.matched) {
break;
+ }
list.push_back(stmt.value);
}
- if (errored)
+ if (errored) {
return Failure::kErrored;
+ }
return list;
});
- if (body.errored)
+ if (body.errored) {
return Failure::kErrored;
+ }
return create<ast::SwitchStatement>(source, condition.value, body.value);
}
@@ -1815,8 +1951,9 @@
// : CASE case_selectors COLON? BRACKET_LEFT case_body BRACKET_RIGHT
// | DEFAULT COLON? BRACKET_LEFT case_body BRACKET_RIGHT
Maybe<const ast::CaseStatement*> ParserImpl::switch_body() {
- if (!peek_is(Token::Type::kCase) && !peek_is(Token::Type::kDefault))
+ if (!peek_is(Token::Type::kCase) && !peek_is(Token::Type::kDefault)) {
return Failure::kNoMatch;
+ }
auto t = next();
auto source = t.source();
@@ -1824,8 +1961,9 @@
ast::CaseSelectorList selector_list;
if (t.Is(Token::Type::kCase)) {
auto selectors = expect_case_selectors();
- if (selectors.errored)
+ if (selectors.errored) {
return Failure::kErrored;
+ }
selector_list = std::move(selectors.value);
}
@@ -1836,10 +1974,12 @@
const char* use = "case statement";
auto body = expect_brace_block(use, [&] { return case_body(); });
- if (body.errored)
+ if (body.errored) {
return Failure::kErrored;
- if (!body.matched)
+ }
+ if (!body.matched) {
return add_error(body.source, "expected case body");
+ }
return create<ast::CaseStatement>(source, selector_list, body.value);
}
@@ -1866,8 +2006,9 @@
}
}
- if (selectors.empty())
+ if (selectors.empty()) {
return add_error(peek(), "unable to parse case selectors");
+ }
return selectors;
}
@@ -1881,18 +2022,21 @@
while (continue_parsing()) {
Source source;
if (match(Token::Type::kFallthrough, &source)) {
- if (!expect("fallthrough statement", Token::Type::kSemicolon))
+ if (!expect("fallthrough statement", Token::Type::kSemicolon)) {
return Failure::kErrored;
+ }
stmts.emplace_back(create<ast::FallthroughStatement>(source));
break;
}
auto stmt = statement();
- if (stmt.errored)
+ if (stmt.errored) {
return Failure::kErrored;
- if (!stmt.matched)
+ }
+ if (!stmt.matched) {
break;
+ }
stmts.emplace_back(stmt.value);
}
@@ -1904,17 +2048,20 @@
// : LOOP BRACKET_LEFT statements continuing_stmt? BRACKET_RIGHT
Maybe<const ast::LoopStatement*> ParserImpl::loop_stmt() {
Source source;
- if (!match(Token::Type::kLoop, &source))
+ if (!match(Token::Type::kLoop, &source)) {
return Failure::kNoMatch;
+ }
return expect_brace_block("loop", [&]() -> Maybe<const ast::LoopStatement*> {
auto stmts = expect_statements();
- if (stmts.errored)
+ if (stmts.errored) {
return Failure::kErrored;
+ }
auto continuing = continuing_stmt();
- if (continuing.errored)
+ if (continuing.errored) {
return Failure::kErrored;
+ }
auto* body = create<ast::BlockStatement>(source, stmts.value);
return create<ast::LoopStatement>(source, body, continuing.value);
@@ -1932,22 +2079,28 @@
// func_call_stmt)?
Maybe<const ast::Statement*> ParserImpl::for_header_initializer() {
auto call = func_call_stmt();
- if (call.errored)
+ if (call.errored) {
return Failure::kErrored;
- if (call.matched)
+ }
+ if (call.matched) {
return call.value;
+ }
auto var = variable_stmt();
- if (var.errored)
+ if (var.errored) {
return Failure::kErrored;
- if (var.matched)
+ }
+ if (var.matched) {
return var.value;
+ }
auto assign = assignment_stmt();
- if (assign.errored)
+ if (assign.errored) {
return Failure::kErrored;
- if (assign.matched)
+ }
+ if (assign.matched) {
return assign.value;
+ }
return Failure::kNoMatch;
}
@@ -1955,16 +2108,20 @@
// (increment_stmt | decrement_stmt | assignment_stmt | func_call_stmt)?
Maybe<const ast::Statement*> ParserImpl::for_header_continuing() {
auto call_stmt = func_call_stmt();
- if (call_stmt.errored)
+ if (call_stmt.errored) {
return Failure::kErrored;
- if (call_stmt.matched)
+ }
+ if (call_stmt.matched) {
return call_stmt.value;
+ }
auto assign = assignment_stmt();
- if (assign.errored)
+ if (assign.errored) {
return Failure::kErrored;
- if (assign.matched)
+ }
+ if (assign.matched) {
return assign.value;
+ }
return Failure::kNoMatch;
}
@@ -1976,22 +2133,27 @@
// (assignment_stmt | func_call_stmt)?
Expect<std::unique_ptr<ForHeader>> ParserImpl::expect_for_header() {
auto initializer = for_header_initializer();
- if (initializer.errored)
+ if (initializer.errored) {
return Failure::kErrored;
+ }
- if (!expect("initializer in for loop", Token::Type::kSemicolon))
+ if (!expect("initializer in for loop", Token::Type::kSemicolon)) {
return Failure::kErrored;
+ }
auto condition = logical_or_expression();
- if (condition.errored)
+ if (condition.errored) {
return Failure::kErrored;
+ }
- if (!expect("condition in for loop", Token::Type::kSemicolon))
+ if (!expect("condition in for loop", Token::Type::kSemicolon)) {
return Failure::kErrored;
+ }
auto continuing = for_header_continuing();
- if (continuing.errored)
+ if (continuing.errored) {
return Failure::kErrored;
+ }
return std::make_unique<ForHeader>(initializer.value, condition.value, continuing.value);
}
@@ -2000,16 +2162,19 @@
// : FOR PAREN_LEFT for_header PAREN_RIGHT BRACE_LEFT statements BRACE_RIGHT
Maybe<const ast::ForLoopStatement*> ParserImpl::for_stmt() {
Source source;
- if (!match(Token::Type::kFor, &source))
+ if (!match(Token::Type::kFor, &source)) {
return Failure::kNoMatch;
+ }
auto header = expect_paren_block("for loop", [&] { return expect_for_header(); });
- if (header.errored)
+ if (header.errored) {
return Failure::kErrored;
+ }
auto stmts = expect_brace_block("for loop", [&] { return expect_statements(); });
- if (stmts.errored)
+ if (stmts.errored) {
return Failure::kErrored;
+ }
return create<ast::ForLoopStatement>(source, header->initializer, header->condition,
header->continuing,
@@ -2021,8 +2186,9 @@
Maybe<const ast::CallStatement*> ParserImpl::func_call_stmt() {
auto t = peek();
auto t2 = peek(1);
- if (!t.IsIdentifier() || !t2.Is(Token::Type::kParenLeft))
+ if (!t.IsIdentifier() || !t2.Is(Token::Type::kParenLeft)) {
return Failure::kNoMatch;
+ }
next(); // Consume the first peek
@@ -2030,8 +2196,9 @@
auto name = t.to_str();
auto params = expect_argument_expression_list("function call");
- if (params.errored)
+ if (params.errored) {
return Failure::kErrored;
+ }
return create<ast::CallStatement>(
source,
@@ -2044,8 +2211,9 @@
// : BREAK
Maybe<const ast::BreakStatement*> ParserImpl::break_stmt() {
Source source;
- if (!match(Token::Type::kBreak, &source))
+ if (!match(Token::Type::kBreak, &source)) {
return Failure::kNoMatch;
+ }
return create<ast::BreakStatement>(source);
}
@@ -2054,8 +2222,9 @@
// : CONTINUE
Maybe<const ast::ContinueStatement*> ParserImpl::continue_stmt() {
Source source;
- if (!match(Token::Type::kContinue, &source))
+ if (!match(Token::Type::kContinue, &source)) {
return Failure::kNoMatch;
+ }
return create<ast::ContinueStatement>(source);
}
@@ -2063,8 +2232,9 @@
// continuing_stmt
// : CONTINUING body_stmt
Maybe<const ast::BlockStatement*> ParserImpl::continuing_stmt() {
- if (!match(Token::Type::kContinuing))
+ if (!match(Token::Type::kContinuing)) {
return create<ast::BlockStatement>(Source{}, ast::StatementList{});
+ }
return expect_body_stmt();
}
@@ -2100,12 +2270,14 @@
const char* use = "bitcast expression";
auto type = expect_lt_gt_block(use, [&] { return expect_type(use); });
- if (type.errored)
+ if (type.errored) {
return Failure::kErrored;
+ }
auto params = expect_paren_rhs_stmt();
- if (params.errored)
+ if (params.errored) {
return Failure::kErrored;
+ }
return create<ast::BitcastExpression>(source, type.value, params.value);
}
@@ -2118,8 +2290,9 @@
if (peek_is(Token::Type::kParenLeft)) {
auto params = expect_argument_expression_list("function call");
- if (params.errored)
+ if (params.errored) {
return Failure::kErrored;
+ }
return create<ast::CallExpression>(source, ident, std::move(params.value));
}
@@ -2128,12 +2301,14 @@
}
auto type = type_decl();
- if (type.errored)
+ if (type.errored) {
return Failure::kErrored;
+ }
if (type.matched) {
auto params = expect_argument_expression_list("type constructor");
- if (params.errored)
+ if (params.errored) {
return Failure::kErrored;
+ }
return builder_.Construct(source, type.value, std::move(params.value));
}
@@ -2152,8 +2327,9 @@
if (match(Token::Type::kBracketLeft, &source)) {
auto res = sync(Token::Type::kBracketRight, [&]() -> Maybe<const ast::Expression*> {
auto param = logical_or_expression();
- if (param.errored)
+ if (param.errored) {
return Failure::kErrored;
+ }
if (!param.matched) {
return add_error(peek(), "unable to parse expression inside []");
}
@@ -2195,10 +2371,12 @@
// : primary_expression postfix_expr
Maybe<const ast::Expression*> ParserImpl::singular_expression() {
auto prefix = primary_expression();
- if (prefix.errored)
+ if (prefix.errored) {
return Failure::kErrored;
- if (!prefix.matched)
+ }
+ if (!prefix.matched) {
return Failure::kNoMatch;
+ }
return postfix_expression(prefix.value);
}
@@ -2289,22 +2467,24 @@
Expect<const ast::Expression*> ParserImpl::expect_multiplicative_expr(const ast::Expression* lhs) {
while (continue_parsing()) {
ast::BinaryOp op = ast::BinaryOp::kNone;
- if (peek_is(Token::Type::kStar))
+ if (peek_is(Token::Type::kStar)) {
op = ast::BinaryOp::kMultiply;
- else if (peek_is(Token::Type::kForwardSlash))
+ } else if (peek_is(Token::Type::kForwardSlash)) {
op = ast::BinaryOp::kDivide;
- else if (peek_is(Token::Type::kMod))
+ } else if (peek_is(Token::Type::kMod)) {
op = ast::BinaryOp::kModulo;
- else
+ } else {
return lhs;
+ }
auto t = next();
auto source = t.source();
auto name = t.to_name();
auto rhs = unary_expression();
- if (rhs.errored)
+ if (rhs.errored) {
return Failure::kErrored;
+ }
if (!rhs.matched) {
return add_error(peek(),
"unable to parse right side of " + std::string(name) + " expression");
@@ -2319,10 +2499,12 @@
// : unary_expression multiplicative_expr
Maybe<const ast::Expression*> ParserImpl::multiplicative_expression() {
auto lhs = unary_expression();
- if (lhs.errored)
+ if (lhs.errored) {
return Failure::kErrored;
- if (!lhs.matched)
+ }
+ if (!lhs.matched) {
return Failure::kNoMatch;
+ }
return expect_multiplicative_expr(lhs.value);
}
@@ -2334,21 +2516,24 @@
Expect<const ast::Expression*> ParserImpl::expect_additive_expr(const ast::Expression* lhs) {
while (continue_parsing()) {
ast::BinaryOp op = ast::BinaryOp::kNone;
- if (peek_is(Token::Type::kPlus))
+ if (peek_is(Token::Type::kPlus)) {
op = ast::BinaryOp::kAdd;
- else if (peek_is(Token::Type::kMinus))
+ } else if (peek_is(Token::Type::kMinus)) {
op = ast::BinaryOp::kSubtract;
- else
+ } else {
return lhs;
+ }
auto t = next();
auto source = t.source();
auto rhs = multiplicative_expression();
- if (rhs.errored)
+ if (rhs.errored) {
return Failure::kErrored;
- if (!rhs.matched)
+ }
+ if (!rhs.matched) {
return add_error(peek(), "unable to parse right side of + expression");
+ }
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
}
@@ -2359,10 +2544,12 @@
// : multiplicative_expression additive_expr
Maybe<const ast::Expression*> ParserImpl::additive_expression() {
auto lhs = multiplicative_expression();
- if (lhs.errored)
+ if (lhs.errored) {
return Failure::kErrored;
- if (!lhs.matched)
+ }
+ if (!lhs.matched) {
return Failure::kNoMatch;
+ }
return expect_additive_expr(lhs.value);
}
@@ -2388,8 +2575,9 @@
auto t = next();
auto source = t.source();
auto rhs = additive_expression();
- if (rhs.errored)
+ if (rhs.errored) {
return Failure::kErrored;
+ }
if (!rhs.matched) {
return add_error(peek(),
std::string("unable to parse right side of ") + name + " expression");
@@ -2404,10 +2592,12 @@
// : additive_expression shift_expr
Maybe<const ast::Expression*> ParserImpl::shift_expression() {
auto lhs = additive_expression();
- if (lhs.errored)
+ if (lhs.errored) {
return Failure::kErrored;
- if (!lhs.matched)
+ }
+ if (!lhs.matched) {
return Failure::kNoMatch;
+ }
return expect_shift_expr(lhs.value);
}
@@ -2421,24 +2611,26 @@
Expect<const ast::Expression*> ParserImpl::expect_relational_expr(const ast::Expression* lhs) {
while (continue_parsing()) {
ast::BinaryOp op = ast::BinaryOp::kNone;
- if (peek_is(Token::Type::kLessThan))
+ if (peek_is(Token::Type::kLessThan)) {
op = ast::BinaryOp::kLessThan;
- else if (peek_is(Token::Type::kGreaterThan))
+ } else if (peek_is(Token::Type::kGreaterThan)) {
op = ast::BinaryOp::kGreaterThan;
- else if (peek_is(Token::Type::kLessThanEqual))
+ } else if (peek_is(Token::Type::kLessThanEqual)) {
op = ast::BinaryOp::kLessThanEqual;
- else if (peek_is(Token::Type::kGreaterThanEqual))
+ } else if (peek_is(Token::Type::kGreaterThanEqual)) {
op = ast::BinaryOp::kGreaterThanEqual;
- else
+ } else {
return lhs;
+ }
auto t = next();
auto source = t.source();
auto name = t.to_name();
auto rhs = shift_expression();
- if (rhs.errored)
+ if (rhs.errored) {
return Failure::kErrored;
+ }
if (!rhs.matched) {
return add_error(peek(),
"unable to parse right side of " + std::string(name) + " expression");
@@ -2453,10 +2645,12 @@
// : shift_expression relational_expr
Maybe<const ast::Expression*> ParserImpl::relational_expression() {
auto lhs = shift_expression();
- if (lhs.errored)
+ if (lhs.errored) {
return Failure::kErrored;
- if (!lhs.matched)
+ }
+ if (!lhs.matched) {
return Failure::kNoMatch;
+ }
return expect_relational_expr(lhs.value);
}
@@ -2468,20 +2662,22 @@
Expect<const ast::Expression*> ParserImpl::expect_equality_expr(const ast::Expression* lhs) {
while (continue_parsing()) {
ast::BinaryOp op = ast::BinaryOp::kNone;
- if (peek_is(Token::Type::kEqualEqual))
+ if (peek_is(Token::Type::kEqualEqual)) {
op = ast::BinaryOp::kEqual;
- else if (peek_is(Token::Type::kNotEqual))
+ } else if (peek_is(Token::Type::kNotEqual)) {
op = ast::BinaryOp::kNotEqual;
- else
+ } else {
return lhs;
+ }
auto t = next();
auto source = t.source();
auto name = t.to_name();
auto rhs = relational_expression();
- if (rhs.errored)
+ if (rhs.errored) {
return Failure::kErrored;
+ }
if (!rhs.matched) {
return add_error(peek(),
"unable to parse right side of " + std::string(name) + " expression");
@@ -2496,10 +2692,12 @@
// : relational_expression equality_expr
Maybe<const ast::Expression*> ParserImpl::equality_expression() {
auto lhs = relational_expression();
- if (lhs.errored)
+ if (lhs.errored) {
return Failure::kErrored;
- if (!lhs.matched)
+ }
+ if (!lhs.matched) {
return Failure::kNoMatch;
+ }
return expect_equality_expr(lhs.value);
}
@@ -2517,10 +2715,12 @@
auto source = t.source();
auto rhs = equality_expression();
- if (rhs.errored)
+ if (rhs.errored) {
return Failure::kErrored;
- if (!rhs.matched)
+ }
+ if (!rhs.matched) {
return add_error(peek(), "unable to parse right side of & expression");
+ }
lhs = create<ast::BinaryExpression>(source, ast::BinaryOp::kAnd, lhs, rhs.value);
}
@@ -2531,10 +2731,12 @@
// : equality_expression and_expr
Maybe<const ast::Expression*> ParserImpl::and_expression() {
auto lhs = equality_expression();
- if (lhs.errored)
+ if (lhs.errored) {
return Failure::kErrored;
- if (!lhs.matched)
+ }
+ if (!lhs.matched) {
return Failure::kNoMatch;
+ }
return expect_and_expr(lhs.value);
}
@@ -2545,14 +2747,17 @@
Expect<const ast::Expression*> ParserImpl::expect_exclusive_or_expr(const ast::Expression* lhs) {
while (continue_parsing()) {
Source source;
- if (!match(Token::Type::kXor, &source))
+ if (!match(Token::Type::kXor, &source)) {
return lhs;
+ }
auto rhs = and_expression();
- if (rhs.errored)
+ if (rhs.errored) {
return Failure::kErrored;
- if (!rhs.matched)
+ }
+ if (!rhs.matched) {
return add_error(peek(), "unable to parse right side of ^ expression");
+ }
lhs = create<ast::BinaryExpression>(source, ast::BinaryOp::kXor, lhs, rhs.value);
}
@@ -2563,10 +2768,12 @@
// : and_expression exclusive_or_expr
Maybe<const ast::Expression*> ParserImpl::exclusive_or_expression() {
auto lhs = and_expression();
- if (lhs.errored)
+ if (lhs.errored) {
return Failure::kErrored;
- if (!lhs.matched)
+ }
+ if (!lhs.matched) {
return Failure::kNoMatch;
+ }
return expect_exclusive_or_expr(lhs.value);
}
@@ -2577,14 +2784,17 @@
Expect<const ast::Expression*> ParserImpl::expect_inclusive_or_expr(const ast::Expression* lhs) {
while (continue_parsing()) {
Source source;
- if (!match(Token::Type::kOr))
+ if (!match(Token::Type::kOr, &source)) {
return lhs;
+ }
auto rhs = exclusive_or_expression();
- if (rhs.errored)
+ if (rhs.errored) {
return Failure::kErrored;
- if (!rhs.matched)
+ }
+ if (!rhs.matched) {
return add_error(peek(), "unable to parse right side of | expression");
+ }
lhs = create<ast::BinaryExpression>(source, ast::BinaryOp::kOr, lhs, rhs.value);
}
@@ -2595,10 +2805,12 @@
// : exclusive_or_expression inclusive_or_expr
Maybe<const ast::Expression*> ParserImpl::inclusive_or_expression() {
auto lhs = exclusive_or_expression();
- if (lhs.errored)
+ if (lhs.errored) {
return Failure::kErrored;
- if (!lhs.matched)
+ }
+ if (!lhs.matched) {
return Failure::kNoMatch;
+ }
return expect_inclusive_or_expr(lhs.value);
}
@@ -2616,10 +2828,12 @@
auto source = t.source();
auto rhs = inclusive_or_expression();
- if (rhs.errored)
+ if (rhs.errored) {
return Failure::kErrored;
- if (!rhs.matched)
+ }
+ if (!rhs.matched) {
return add_error(peek(), "unable to parse right side of && expression");
+ }
lhs = create<ast::BinaryExpression>(source, ast::BinaryOp::kLogicalAnd, lhs, rhs.value);
}
@@ -2630,10 +2844,12 @@
// : inclusive_or_expression logical_and_expr
Maybe<const ast::Expression*> ParserImpl::logical_and_expression() {
auto lhs = inclusive_or_expression();
- if (lhs.errored)
+ if (lhs.errored) {
return Failure::kErrored;
- if (!lhs.matched)
+ }
+ if (!lhs.matched) {
return Failure::kNoMatch;
+ }
return expect_logical_and_expr(lhs.value);
}
@@ -2644,14 +2860,17 @@
Expect<const ast::Expression*> ParserImpl::expect_logical_or_expr(const ast::Expression* lhs) {
while (continue_parsing()) {
Source source;
- if (!match(Token::Type::kOrOr))
+ if (!match(Token::Type::kOrOr, &source)) {
return lhs;
+ }
auto rhs = logical_and_expression();
- if (rhs.errored)
+ if (rhs.errored) {
return Failure::kErrored;
- if (!rhs.matched)
+ }
+ if (!rhs.matched) {
return add_error(peek(), "unable to parse right side of || expression");
+ }
lhs = create<ast::BinaryExpression>(source, ast::BinaryOp::kLogicalOr, lhs, rhs.value);
}
@@ -2662,10 +2881,12 @@
// : logical_and_expression logical_or_expr
Maybe<const ast::Expression*> ParserImpl::logical_or_expression() {
auto lhs = logical_and_expression();
- if (lhs.errored)
+ if (lhs.errored) {
return Failure::kErrored;
- if (!lhs.matched)
+ }
+ if (!lhs.matched) {
return Failure::kNoMatch;
+ }
return expect_logical_or_expr(lhs.value);
}
@@ -2852,8 +3073,9 @@
return list;
});
- if (params.errored)
+ if (params.errored) {
return Failure::kErrored;
+ }
return builder_.Construct(source, type.value, params.value);
}
@@ -2876,11 +3098,13 @@
}
}
- if (errored)
+ if (errored) {
return Failure::kErrored;
+ }
- if (attrs.empty())
+ if (attrs.empty()) {
return Failure::kNoMatch;
+ }
return attrs;
}
@@ -2888,10 +3112,12 @@
Expect<const ast::Attribute*> ParserImpl::expect_attribute() {
auto t = peek();
auto attr = attribute();
- if (attr.errored)
+ if (attr.errored) {
return Failure::kErrored;
- if (attr.matched)
+ }
+ if (attr.matched) {
return attr.value;
+ }
return add_error(t, "expected attribute");
}
@@ -2907,8 +3133,9 @@
const char* use = "location attribute";
return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use);
- if (val.errored)
+ if (val.errored) {
return Failure::kErrored;
+ }
return create<ast::LocationAttribute>(t.source(), val.value);
});
@@ -2918,8 +3145,9 @@
const char* use = "binding attribute";
return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use);
- if (val.errored)
+ if (val.errored) {
return Failure::kErrored;
+ }
return create<ast::BindingAttribute>(t.source(), val.value);
});
@@ -2929,8 +3157,9 @@
const char* use = "group attribute";
return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use);
- if (val.errored)
+ if (val.errored) {
return Failure::kErrored;
+ }
return create<ast::GroupAttribute>(t.source(), val.value);
});
@@ -2976,8 +3205,9 @@
if (t == kBuiltinAttribute) {
return expect_paren_block("builtin attribute", [&]() -> Result {
auto builtin = expect_builtin();
- if (builtin.errored)
+ if (builtin.errored) {
return Failure::kErrored;
+ }
return create<ast::BuiltinAttribute>(t.source(), builtin.value);
});
@@ -3024,8 +3254,9 @@
if (t == kStageAttribute) {
return expect_paren_block("stage attribute", [&]() -> Result {
auto stage = expect_pipeline_stage();
- if (stage.errored)
+ if (stage.errored) {
return Failure::kErrored;
+ }
return create<ast::StageAttribute>(t.source(), stage.value);
});
@@ -3035,8 +3266,9 @@
const char* use = "size attribute";
return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use);
- if (val.errored)
+ if (val.errored) {
return Failure::kErrored;
+ }
return create<ast::StructMemberSizeAttribute>(t.source(), val.value);
});
@@ -3046,8 +3278,9 @@
const char* use = "align attribute";
return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use);
- if (val.errored)
+ if (val.errored) {
return Failure::kErrored;
+ }
return create<ast::StructMemberAlignAttribute>(t.source(), val.value);
});
@@ -3057,8 +3290,9 @@
const char* use = "id attribute";
return expect_paren_block(use, [&]() -> Result {
auto val = expect_positive_sint(use);
- if (val.errored)
+ if (val.errored) {
return Failure::kErrored;
+ }
return create<ast::IdAttribute>(t.source(), val.value);
});
@@ -3078,8 +3312,9 @@
bool ParserImpl::match(Token::Type tok, Source* source /*= nullptr*/) {
auto t = peek();
- if (source != nullptr)
+ if (source != nullptr) {
*source = t.source();
+ }
if (t.Is(tok)) {
next();
@@ -3148,22 +3383,26 @@
Expect<uint32_t> ParserImpl::expect_positive_sint(std::string_view use) {
auto sint = expect_sint(use);
- if (sint.errored)
+ if (sint.errored) {
return Failure::kErrored;
+ }
- if (sint.value < 0)
+ if (sint.value < 0) {
return add_error(sint.source, std::string(use) + " must be positive");
+ }
return {static_cast<uint32_t>(sint.value), sint.source};
}
Expect<uint32_t> ParserImpl::expect_nonzero_positive_sint(std::string_view use) {
auto sint = expect_sint(use);
- if (sint.errored)
+ if (sint.errored) {
return Failure::kErrored;
+ }
- if (sint.value <= 0)
+ if (sint.value <= 0) {
return add_error(sint.source, std::string(use) + " must be greater than 0");
+ }
return {static_cast<uint32_t>(sint.value), sint.source};
}
@@ -3196,11 +3435,13 @@
return sync(end, [&]() -> T {
auto res = body();
- if (res.errored)
+ if (res.errored) {
return Failure::kErrored;
+ }
- if (!expect(use, end))
+ if (!expect(use, end)) {
return Failure::kErrored;
+ }
return res;
});
diff --git a/src/tint/reader/wgsl/parser_impl_additive_expression_test.cc b/src/tint/reader/wgsl/parser_impl_additive_expression_test.cc
index 51cf90e..4573b84 100644
--- a/src/tint/reader/wgsl/parser_impl_additive_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_additive_expression_test.cc
@@ -25,6 +25,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 4u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kAdd, rel->op);
diff --git a/src/tint/reader/wgsl/parser_impl_and_expression_test.cc b/src/tint/reader/wgsl/parser_impl_and_expression_test.cc
index 1ed8a9c..fd90460 100644
--- a/src/tint/reader/wgsl/parser_impl_and_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_and_expression_test.cc
@@ -25,6 +25,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 4u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kAnd, rel->op);
diff --git a/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc b/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
index 0fd6b80..bdf7eeb 100644
--- a/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
@@ -23,41 +23,36 @@
// Test a valid enable directive.
TEST_F(EnableDirectiveTest, Valid) {
- auto p = parser("enable InternalExtensionForTesting;");
+ auto p = parser("enable f16;");
p->enable_directive();
EXPECT_FALSE(p->has_error()) << p->error();
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Extensions(),
- ast::ExtensionSet{ast::Enable::ExtensionKind::kInternalExtensionForTesting});
- EXPECT_EQ(ast.GlobalDeclarations().size(), 1u);
- auto* node = ast.GlobalDeclarations()[0]->As<ast::Enable>();
- EXPECT_TRUE(node != nullptr);
- EXPECT_EQ(node->name, "InternalExtensionForTesting");
- EXPECT_EQ(node->kind, ast::Enable::ExtensionKind::kInternalExtensionForTesting);
+ ASSERT_EQ(ast.Enables().size(), 1u);
+ auto* enable = ast.Enables()[0];
+ EXPECT_EQ(enable->extension, ast::Extension::kF16);
+ ASSERT_EQ(ast.GlobalDeclarations().size(), 1u);
+ EXPECT_EQ(ast.GlobalDeclarations()[0], enable);
}
// Test multiple enable directives for a same extension.
TEST_F(EnableDirectiveTest, EnableMultipleTime) {
auto p = parser(R"(
-enable InternalExtensionForTesting;
-enable InternalExtensionForTesting;
+enable f16;
+enable f16;
)");
p->translation_unit();
EXPECT_FALSE(p->has_error()) << p->error();
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Extensions(),
- ast::ExtensionSet{ast::Enable::ExtensionKind::kInternalExtensionForTesting});
- EXPECT_EQ(ast.GlobalDeclarations().size(), 2u);
- auto* node1 = ast.GlobalDeclarations()[0]->As<ast::Enable>();
- EXPECT_TRUE(node1 != nullptr);
- EXPECT_EQ(node1->name, "InternalExtensionForTesting");
- EXPECT_EQ(node1->kind, ast::Enable::ExtensionKind::kInternalExtensionForTesting);
- auto* node2 = ast.GlobalDeclarations()[1]->As<ast::Enable>();
- EXPECT_TRUE(node2 != nullptr);
- EXPECT_EQ(node2->name, "InternalExtensionForTesting");
- EXPECT_EQ(node2->kind, ast::Enable::ExtensionKind::kInternalExtensionForTesting);
+ ASSERT_EQ(ast.Enables().size(), 2u);
+ auto* enable_a = ast.Enables()[0];
+ auto* enable_b = ast.Enables()[1];
+ EXPECT_EQ(enable_a->extension, ast::Extension::kF16);
+ EXPECT_EQ(enable_b->extension, ast::Extension::kF16);
+ ASSERT_EQ(ast.GlobalDeclarations().size(), 2u);
+ EXPECT_EQ(ast.GlobalDeclarations()[0], enable_a);
+ EXPECT_EQ(ast.GlobalDeclarations()[1], enable_b);
}
// Test an unknown extension identifier.
@@ -69,42 +64,42 @@
EXPECT_EQ(p->error(), "1:8: unsupported extension: 'NotAValidExtensionName'");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Extensions().size(), 0u);
+ EXPECT_EQ(ast.Enables().size(), 0u);
EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
}
-// Test an enable directive missing ending semiclon.
-TEST_F(EnableDirectiveTest, MissingEndingSemiclon) {
- auto p = parser("enable InternalExtensionForTesting");
+// Test an enable directive missing ending semicolon.
+TEST_F(EnableDirectiveTest, MissingEndingSemicolon) {
+ auto p = parser("enable f16");
p->translation_unit();
EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:35: expected ';' for enable directive");
+ EXPECT_EQ(p->error(), "1:11: expected ';' for enable directive");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Extensions().size(), 0u);
+ EXPECT_EQ(ast.Enables().size(), 0u);
EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
}
// Test using invalid tokens in an enable directive.
TEST_F(EnableDirectiveTest, InvalidTokens) {
{
- auto p = parser("enable InternalExtensionForTesting<;");
+ auto p = parser("enable f16<;");
p->translation_unit();
EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:35: expected ';' for enable directive");
+ EXPECT_EQ(p->error(), "1:11: expected ';' for enable directive");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Extensions().size(), 0u);
+ EXPECT_EQ(ast.Enables().size(), 0u);
EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
}
{
- auto p = parser("enable <InternalExtensionForTesting;");
+ auto p = parser("enable <f16;");
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:8: invalid extension name");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Extensions().size(), 0u);
+ EXPECT_EQ(ast.Enables().size(), 0u);
EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
}
{
@@ -114,7 +109,7 @@
EXPECT_EQ(p->error(), "1:8: invalid extension name");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Extensions().size(), 0u);
+ EXPECT_EQ(ast.Enables().size(), 0u);
EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
}
{
@@ -124,7 +119,7 @@
EXPECT_EQ(p->error(), "1:8: invalid extension name");
auto program = p->program();
auto& ast = program.AST();
- EXPECT_EQ(ast.Extensions().size(), 0u);
+ EXPECT_EQ(ast.Enables().size(), 0u);
EXPECT_EQ(ast.GlobalDeclarations().size(), 0u);
}
}
@@ -133,35 +128,39 @@
TEST_F(EnableDirectiveTest, FollowingOtherGlobalDecl) {
auto p = parser(R"(
var<private> t: f32 = 0f;
-enable InternalExtensionForTesting;
+enable f16;
)");
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "3:1: enable directives must come before all global declarations");
auto program = p->program();
auto& ast = program.AST();
- // Accept the enable directive although it cause an error
- EXPECT_EQ(ast.Extensions(),
- ast::ExtensionSet{ast::Enable::ExtensionKind::kInternalExtensionForTesting});
- EXPECT_EQ(ast.GlobalDeclarations().size(), 2u);
+ // Accept the enable directive although it caused an error
+ ASSERT_EQ(ast.Enables().size(), 1u);
+ auto* enable = ast.Enables()[0];
+ EXPECT_EQ(enable->extension, ast::Extension::kF16);
+ ASSERT_EQ(ast.GlobalDeclarations().size(), 2u);
+ EXPECT_EQ(ast.GlobalDeclarations()[1], enable);
}
-// Test an enable directive go after an empty semiclon.
-TEST_F(EnableDirectiveTest, FollowingEmptySemiclon) {
+// Test an enable directive go after an empty semicolon.
+TEST_F(EnableDirectiveTest, FollowingEmptySemicolon) {
auto p = parser(R"(
;
-enable InternalExtensionForTesting;
+enable f16;
)");
p->translation_unit();
- // An empty semiclon is treated as a global declaration
+ // An empty semicolon is treated as a global declaration
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "3:1: enable directives must come before all global declarations");
auto program = p->program();
auto& ast = program.AST();
// Accept the enable directive although it cause an error
- EXPECT_EQ(ast.Extensions(),
- ast::ExtensionSet{ast::Enable::ExtensionKind::kInternalExtensionForTesting});
- EXPECT_EQ(ast.GlobalDeclarations().size(), 1u);
+ ASSERT_EQ(ast.Enables().size(), 1u);
+ auto* enable = ast.Enables()[0];
+ EXPECT_EQ(enable->extension, ast::Extension::kF16);
+ ASSERT_EQ(ast.GlobalDeclarations().size(), 1u);
+ EXPECT_EQ(ast.GlobalDeclarations()[0], enable);
}
} // namespace
diff --git a/src/tint/reader/wgsl/parser_impl_equality_expression_test.cc b/src/tint/reader/wgsl/parser_impl_equality_expression_test.cc
index 4e1f5a3..158227d 100644
--- a/src/tint/reader/wgsl/parser_impl_equality_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_equality_expression_test.cc
@@ -25,6 +25,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 5u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kEqual, rel->op);
@@ -45,6 +50,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 5u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kNotEqual, rel->op);
diff --git a/src/tint/reader/wgsl/parser_impl_exclusive_or_expression_test.cc b/src/tint/reader/wgsl/parser_impl_exclusive_or_expression_test.cc
index c6f8ad4..2994ae8 100644
--- a/src/tint/reader/wgsl/parser_impl_exclusive_or_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_exclusive_or_expression_test.cc
@@ -25,6 +25,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 4u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kXor, rel->op);
diff --git a/src/tint/reader/wgsl/parser_impl_inclusive_or_expression_test.cc b/src/tint/reader/wgsl/parser_impl_inclusive_or_expression_test.cc
index 83b9358..f534ff7 100644
--- a/src/tint/reader/wgsl/parser_impl_inclusive_or_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_inclusive_or_expression_test.cc
@@ -25,6 +25,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 4u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kOr, rel->op);
diff --git a/src/tint/reader/wgsl/parser_impl_logical_and_expression_test.cc b/src/tint/reader/wgsl/parser_impl_logical_and_expression_test.cc
index 57624a5..8baadaf 100644
--- a/src/tint/reader/wgsl/parser_impl_logical_and_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_logical_and_expression_test.cc
@@ -25,6 +25,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 5u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kLogicalAnd, rel->op);
diff --git a/src/tint/reader/wgsl/parser_impl_logical_or_expression_test.cc b/src/tint/reader/wgsl/parser_impl_logical_or_expression_test.cc
index 6bde6bd..943b059 100644
--- a/src/tint/reader/wgsl/parser_impl_logical_or_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_logical_or_expression_test.cc
@@ -25,6 +25,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 5u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kLogicalOr, rel->op);
diff --git a/src/tint/reader/wgsl/parser_impl_multiplicative_expression_test.cc b/src/tint/reader/wgsl/parser_impl_multiplicative_expression_test.cc
index 6d77fd5..28ac568 100644
--- a/src/tint/reader/wgsl/parser_impl_multiplicative_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_multiplicative_expression_test.cc
@@ -25,6 +25,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 4u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kMultiply, rel->op);
diff --git a/src/tint/reader/wgsl/parser_impl_relational_expression_test.cc b/src/tint/reader/wgsl/parser_impl_relational_expression_test.cc
index 725761b..7ad161f 100644
--- a/src/tint/reader/wgsl/parser_impl_relational_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_relational_expression_test.cc
@@ -25,6 +25,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 4u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kLessThan, rel->op);
@@ -45,6 +50,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 4u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kGreaterThan, rel->op);
@@ -65,6 +75,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 5u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kLessThanEqual, rel->op);
@@ -85,6 +100,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 5u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kGreaterThanEqual, rel->op);
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 3226ef5..e840af7 100644
--- a/src/tint/reader/wgsl/parser_impl_reserved_keyword_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_reserved_keyword_test.cc
@@ -88,7 +88,6 @@
"const",
"do",
"enum",
- "f16",
"f64",
"handle",
"i8",
diff --git a/src/tint/reader/wgsl/parser_impl_shift_expression_test.cc b/src/tint/reader/wgsl/parser_impl_shift_expression_test.cc
index fd612b5..83c1255 100644
--- a/src/tint/reader/wgsl/parser_impl_shift_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_shift_expression_test.cc
@@ -25,6 +25,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 5u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kShiftLeft, rel->op);
@@ -45,6 +50,11 @@
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
+ EXPECT_EQ(e->source.range.begin.line, 1u);
+ EXPECT_EQ(e->source.range.begin.column, 3u);
+ EXPECT_EQ(e->source.range.end.line, 1u);
+ EXPECT_EQ(e->source.range.end.column, 5u);
+
ASSERT_TRUE(e->Is<ast::BinaryExpression>());
auto* rel = e->As<ast::BinaryExpression>();
EXPECT_EQ(ast::BinaryOp::kShiftRight, rel->op);
diff --git a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
index a721d77..bc2bfe5 100644
--- a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
@@ -55,6 +55,17 @@
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
}
+TEST_F(ParserImplTest, TypeDecl_F16) {
+ auto p = parser("f16");
+
+ auto t = p->type_decl();
+ EXPECT_TRUE(t.matched);
+ EXPECT_FALSE(t.errored);
+ ASSERT_NE(t.value, nullptr) << p->error();
+ ASSERT_TRUE(t.value->Is<ast::F16>());
+ EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 4u}}));
+}
+
TEST_F(ParserImplTest, TypeDecl_F32) {
auto p = parser("f32");
diff --git a/src/tint/reader/wgsl/token.cc b/src/tint/reader/wgsl/token.cc
index 06eb6fb..4680eee 100644
--- a/src/tint/reader/wgsl/token.cc
+++ b/src/tint/reader/wgsl/token.cc
@@ -151,6 +151,8 @@
return "else";
case Token::Type::kEnable:
return "enable";
+ case Token::Type::kF16:
+ return "f16";
case Token::Type::kF32:
return "f32";
case Token::Type::kFallthrough:
diff --git a/src/tint/reader/wgsl/token.h b/src/tint/reader/wgsl/token.h
index 82b3fab..0a68f9b0 100644
--- a/src/tint/reader/wgsl/token.h
+++ b/src/tint/reader/wgsl/token.h
@@ -162,6 +162,8 @@
kElse,
/// A 'enable'
kEnable,
+ /// A 'f16'
+ kF16,
/// A 'f32'
kF32,
/// A 'fallthrough'
diff --git a/src/tint/resolver/builtin_test.cc b/src/tint/resolver/builtin_test.cc
index 6020eae..74a898c 100644
--- a/src/tint/resolver/builtin_test.cc
+++ b/src/tint/resolver/builtin_test.cc
@@ -1924,7 +1924,7 @@
}
}
- auto* call_sem = Sem().Get(call);
+ auto* call_sem = Sem().Get<sem::Call>(call);
ASSERT_NE(call_sem, nullptr);
auto* target = call_sem->Target();
ASSERT_NE(target, nullptr);
diff --git a/src/tint/resolver/builtin_validation_test.cc b/src/tint/resolver/builtin_validation_test.cc
index 0e48b55..770d8d0 100644
--- a/src/tint/resolver/builtin_validation_test.cc
+++ b/src/tint/resolver/builtin_validation_test.cc
@@ -378,10 +378,7 @@
TEST_F(ResolverDP4aExtensionValidationTest, Dot4I8PackedWithExtension) {
// enable chromium_experimental_dp4a;
// fn func { return dot4I8Packed(1u, 2u); }
- auto* ext =
- create<ast::Enable>(Source{Source::Range{Source::Location{10, 2}, Source::Location{10, 5}}},
- "chromium_experimental_dp4a");
- AST().AddEnable(ext);
+ Enable(ast::Extension::kChromiumExperimentalDP4a);
Func("func", {}, ty.i32(),
{
@@ -409,10 +406,7 @@
TEST_F(ResolverDP4aExtensionValidationTest, Dot4U8PackedWithExtension) {
// enable chromium_experimental_dp4a;
// fn func { return dot4U8Packed(1u, 2u); }
- auto* ext =
- create<ast::Enable>(Source{Source::Range{Source::Location{10, 2}, Source::Location{10, 5}}},
- "chromium_experimental_dp4a");
- AST().AddEnable(ext);
+ Enable(ast::Extension::kChromiumExperimentalDP4a);
Func("func", {}, ty.u32(),
{
diff --git a/src/tint/resolver/call_test.cc b/src/tint/resolver/call_test.cc
index d84f300..39a6eb4 100644
--- a/src/tint/resolver/call_test.cc
+++ b/src/tint/resolver/call_test.cc
@@ -94,7 +94,7 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
- auto* call = Sem().Get(call_expr);
+ auto* call = Sem().Get<sem::Call>(call_expr);
EXPECT_NE(call, nullptr);
EXPECT_EQ(call->Target(), Sem().Get(func));
}
@@ -106,7 +106,7 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
- auto* call = Sem().Get(call_expr);
+ auto* call = Sem().Get<sem::Call>(call_expr);
EXPECT_NE(call, nullptr);
EXPECT_EQ(call->Target(), Sem().Get(b));
}
diff --git a/src/tint/resolver/compound_statement_test.cc b/src/tint/resolver/compound_statement_test.cc
index 4061a62..0444bd3 100644
--- a/src/tint/resolver/compound_statement_test.cc
+++ b/src/tint/resolver/compound_statement_test.cc
@@ -144,6 +144,35 @@
}
}
+TEST_F(ResolverCompoundStatementTest, Loop_EmptyContinuing) {
+ // fn F() {
+ // loop {
+ // break;
+ // continuing {
+ // }
+ // }
+ // }
+ auto* brk = Break();
+ auto* loop = Loop(Block(brk), Block());
+ Func("F", {}, ty.void_(), {loop});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ {
+ auto* s = Sem().Get(loop);
+ ASSERT_NE(s, nullptr);
+ EXPECT_TRUE(s->Is<sem::LoopStatement>());
+ EXPECT_EQ(s->Parent(), s->FindFirstParent<sem::FunctionBlockStatement>());
+ EXPECT_EQ(s->Parent(), s->Block());
+ }
+ {
+ auto* s = Sem().Get(loop->continuing);
+ ASSERT_NE(s, nullptr);
+ EXPECT_TRUE(Is<sem::LoopContinuingBlockStatement>(s));
+ EXPECT_TRUE(Is<sem::LoopStatement>(s->Parent()->Parent()));
+ }
+}
+
TEST_F(ResolverCompoundStatementTest, ForLoop) {
// fn F() {
// for (var i : u32; true; i = i + 1u) {
diff --git a/src/tint/resolver/ctor_conv_intrinsic.cc b/src/tint/resolver/ctor_conv_intrinsic.cc
new file mode 100644
index 0000000..5618fba
--- /dev/null
+++ b/src/tint/resolver/ctor_conv_intrinsic.cc
@@ -0,0 +1,70 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/intrinsic-gen
+// using the template:
+// src/tint/resolver/ctor_conv_intrinsic.cc.tmpl
+// and the intrinsic defintion file:
+// src/tint/intrinsics.def
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/resolver/ctor_conv_intrinsic.h"
+
+namespace tint::resolver {
+
+const char* str(CtorConvIntrinsic i) {
+ switch (i) {
+ case CtorConvIntrinsic::kNone:
+ return "<none>";
+ case CtorConvIntrinsic::kI32:
+ return "i32";
+ case CtorConvIntrinsic::kU32:
+ return "u32";
+ case CtorConvIntrinsic::kF32:
+ return "f32";
+ case CtorConvIntrinsic::kBool:
+ return "bool";
+ case CtorConvIntrinsic::kVec2:
+ return "vec2";
+ case CtorConvIntrinsic::kVec3:
+ return "vec3";
+ case CtorConvIntrinsic::kVec4:
+ return "vec4";
+ case CtorConvIntrinsic::kMat2x2:
+ return "mat2x2";
+ case CtorConvIntrinsic::kMat2x3:
+ return "mat2x3";
+ case CtorConvIntrinsic::kMat2x4:
+ return "mat2x4";
+ case CtorConvIntrinsic::kMat3x2:
+ return "mat3x2";
+ case CtorConvIntrinsic::kMat3x3:
+ return "mat3x3";
+ case CtorConvIntrinsic::kMat3x4:
+ return "mat3x4";
+ case CtorConvIntrinsic::kMat4x2:
+ return "mat4x2";
+ case CtorConvIntrinsic::kMat4x3:
+ return "mat4x3";
+ case CtorConvIntrinsic::kMat4x4:
+ return "mat4x4";
+ }
+ return "<unknown>";
+}
+
+} // namespace tint::resolver
+
diff --git a/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl b/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl
new file mode 100644
index 0000000..ac98c4d
--- /dev/null
+++ b/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl
@@ -0,0 +1,28 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/builtin-gen to generate ctor_conv_intrinsic.cc
+
+See:
+* tools/cmd/intrinsic-gen/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+#include "src/tint/resolver/ctor_conv_intrinsic.h"
+
+namespace tint::resolver {
+
+const char* str(CtorConvIntrinsic i) {
+ switch (i) {
+ case CtorConvIntrinsic::kNone:
+ return "<none>";
+{{- range .Sem.ConstructorsAndConverters }}
+ case CtorConvIntrinsic::k{{Title .Name}}:
+ return "{{.Name}}";
+{{- end }}
+ }
+ return "<unknown>";
+}
+
+} // namespace tint::resolver
+
diff --git a/src/tint/resolver/ctor_conv_intrinsic.h b/src/tint/resolver/ctor_conv_intrinsic.h
new file mode 100644
index 0000000..7c68658
--- /dev/null
+++ b/src/tint/resolver/ctor_conv_intrinsic.h
@@ -0,0 +1,100 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/intrinsic-gen
+// using the template:
+// src/tint/resolver/ctor_conv_intrinsic.h.tmpl
+// and the intrinsic defintion file:
+// src/tint/intrinsics.def
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SRC_TINT_RESOLVER_CTOR_CONV_INTRINSIC_H_
+#define SRC_TINT_RESOLVER_CTOR_CONV_INTRINSIC_H_
+
+#include <cstdint>
+
+namespace tint::resolver {
+
+/// CtorConvIntrinsic is an enumerator of types that have a constructor or converter overload
+/// declared in the intrinsic table.
+enum class CtorConvIntrinsic {
+ kNone = -1,
+ kI32,
+ kU32,
+ kF32,
+ kBool,
+ kVec2,
+ kVec3,
+ kVec4,
+ kMat2x2,
+ kMat2x3,
+ kMat2x4,
+ kMat3x2,
+ kMat3x3,
+ kMat3x4,
+ kMat4x2,
+ kMat4x3,
+ kMat4x4,
+};
+
+/// @returns the name of the type.
+const char* str(CtorConvIntrinsic i);
+
+/// @param n the width of the vector
+/// @return the CtorConvIntrinsic for a vector of width `n`
+inline CtorConvIntrinsic VectorCtorConvIntrinsic(uint32_t n) {
+ switch (n) {
+ case 2:
+ return CtorConvIntrinsic::kVec2;
+ case 3:
+ return CtorConvIntrinsic::kVec3;
+ case 4:
+ return CtorConvIntrinsic::kVec4;
+ }
+ return CtorConvIntrinsic::kNone;
+}
+
+/// @param c the number of columns in the matrix
+/// @param r the number of rows in the matrix
+/// @return the CtorConvIntrinsic for a matrix with `c` columns and `r` rows
+inline CtorConvIntrinsic MatrixCtorConvIntrinsic(uint32_t c, uint32_t r) {
+ switch ((c - 2) * 3 + (r - 2)) {
+ case 0:
+ return CtorConvIntrinsic::kMat2x2;
+ case 1:
+ return CtorConvIntrinsic::kMat2x3;
+ case 2:
+ return CtorConvIntrinsic::kMat2x4;
+ case 3:
+ return CtorConvIntrinsic::kMat3x2;
+ case 4:
+ return CtorConvIntrinsic::kMat3x3;
+ case 5:
+ return CtorConvIntrinsic::kMat3x4;
+ case 6:
+ return CtorConvIntrinsic::kMat4x2;
+ case 7:
+ return CtorConvIntrinsic::kMat4x3;
+ case 8:
+ return CtorConvIntrinsic::kMat4x4;
+ }
+ return CtorConvIntrinsic::kNone;
+}
+
+} // namespace tint::resolver
+
+#endif // SRC_TINT_RESOLVER_CTOR_CONV_INTRINSIC_H_
diff --git a/src/tint/resolver/ctor_conv_intrinsic.h.tmpl b/src/tint/resolver/ctor_conv_intrinsic.h.tmpl
new file mode 100644
index 0000000..9c0da25
--- /dev/null
+++ b/src/tint/resolver/ctor_conv_intrinsic.h.tmpl
@@ -0,0 +1,73 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/builtin-gen to generate ctor_conv_intrinsic.h
+
+See:
+* tools/cmd/intrinsic-gen/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+#ifndef SRC_TINT_RESOLVER_CTOR_CONV_INTRINSIC_H_
+#define SRC_TINT_RESOLVER_CTOR_CONV_INTRINSIC_H_
+
+#include <cstdint>
+
+namespace tint::resolver {
+
+/// CtorConvIntrinsic is an enumerator of types that have a constructor or converter overload
+/// declared in the intrinsic table.
+enum class CtorConvIntrinsic {
+ kNone = -1,
+{{- range .Sem.ConstructorsAndConverters }}
+ k{{Title .Name}},
+{{- end }}
+};
+
+/// @returns the name of the type.
+const char* str(CtorConvIntrinsic i);
+
+/// @param n the width of the vector
+/// @return the CtorConvIntrinsic for a vector of width `n`
+inline CtorConvIntrinsic VectorCtorConvIntrinsic(uint32_t n) {
+ switch (n) {
+ case 2:
+ return CtorConvIntrinsic::kVec2;
+ case 3:
+ return CtorConvIntrinsic::kVec3;
+ case 4:
+ return CtorConvIntrinsic::kVec4;
+ }
+ return CtorConvIntrinsic::kNone;
+}
+
+/// @param c the number of columns in the matrix
+/// @param r the number of rows in the matrix
+/// @return the CtorConvIntrinsic for a matrix with `c` columns and `r` rows
+inline CtorConvIntrinsic MatrixCtorConvIntrinsic(uint32_t c, uint32_t r) {
+ switch ((c - 2) * 3 + (r - 2)) {
+ case 0:
+ return CtorConvIntrinsic::kMat2x2;
+ case 1:
+ return CtorConvIntrinsic::kMat2x3;
+ case 2:
+ return CtorConvIntrinsic::kMat2x4;
+ case 3:
+ return CtorConvIntrinsic::kMat3x2;
+ case 4:
+ return CtorConvIntrinsic::kMat3x3;
+ case 5:
+ return CtorConvIntrinsic::kMat3x4;
+ case 6:
+ return CtorConvIntrinsic::kMat4x2;
+ case 7:
+ return CtorConvIntrinsic::kMat4x3;
+ case 8:
+ return CtorConvIntrinsic::kMat4x4;
+ }
+ return CtorConvIntrinsic::kNone;
+}
+
+} // namespace tint::resolver
+
+#endif // SRC_TINT_RESOLVER_CTOR_CONV_INTRINSIC_H_
diff --git a/src/tint/resolver/dependency_graph.cc b/src/tint/resolver/dependency_graph.cc
index 0a9bdc0..7e66899 100644
--- a/src/tint/resolver/dependency_graph.cc
+++ b/src/tint/resolver/dependency_graph.cc
@@ -342,7 +342,7 @@
TraverseType(tex->type);
},
[&](Default) {
- if (!ty->IsAnyOf<ast::Void, ast::Bool, ast::I32, ast::U32, ast::F32,
+ if (!ty->IsAnyOf<ast::Void, ast::Bool, ast::I32, ast::U32, ast::F16, ast::F32,
ast::DepthTexture, ast::DepthMultisampledTexture,
ast::StorageTexture, ast::ExternalTexture, ast::Sampler>()) {
UnhandledNode(diagnostics_, ty);
@@ -420,7 +420,7 @@
DependencyGraph& graph_;
DependencyEdges& dependency_edges_;
- ScopeStack<const ast::Node*> scope_stack_;
+ ScopeStack<Symbol, const ast::Node*> scope_stack_;
Global* current_global_ = nullptr;
};
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index fa9dbf8..6c19f7c 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -20,6 +20,9 @@
#include <utility>
#include "src/tint/program_builder.h"
+#include "src/tint/sem/abstract_float.h"
+#include "src/tint/sem/abstract_int.h"
+#include "src/tint/sem/abstract_numeric.h"
#include "src/tint/sem/atomic.h"
#include "src/tint/sem/depth_multisampled_texture.h"
#include "src/tint/sem/depth_texture.h"
@@ -28,12 +31,14 @@
#include "src/tint/sem/pipeline_stage_set.h"
#include "src/tint/sem/sampled_texture.h"
#include "src/tint/sem/storage_texture.h"
+#include "src/tint/sem/type_constructor.h"
+#include "src/tint/sem/type_conversion.h"
#include "src/tint/utils/hash.h"
#include "src/tint/utils/map.h"
#include "src/tint/utils/math.h"
#include "src/tint/utils/scoped_assignment.h"
-namespace tint {
+namespace tint::resolver {
namespace {
// Forward declarations
@@ -98,83 +103,86 @@
const Number Number::any{Number::kAny};
const Number Number::invalid{Number::kInvalid};
-/// ClosedState holds the state of the open / closed numbers and types.
+/// TemplateState holds the state of the template numbers and types.
/// Used by the MatchState.
-class ClosedState {
+class TemplateState {
public:
- explicit ClosedState(ProgramBuilder& b) : builder(b) {}
-
- /// If the type with index `idx` is open, then it is closed with type `ty` and
- /// Type() returns true. If the type is closed, then `Type()` returns true iff
- /// it is equal to `ty`.
- bool Type(uint32_t idx, const sem::Type* ty) {
+ /// If the template type with index `idx` is undefined, then it is defined with the `ty` and
+ /// Type() returns `ty`.
+ /// If the template type is defined, and `ty` can be converted to the template type then the
+ /// template type is returned.
+ /// If the template type is defined, and the template type can be converted to `ty`, then the
+ /// template type is replaced with `ty`, and `ty` is returned.
+ /// If none of the above applies, then `ty` is a type mismatch for the template type, and
+ /// nullptr is returned.
+ const sem::Type* Type(size_t idx, const sem::Type* ty) {
auto res = types_.emplace(idx, ty);
- return res.second || res.first->second == ty;
+ if (res.second) {
+ return ty;
+ }
+ auto* existing = res.first->second;
+ if (existing == ty) {
+ return ty;
+ }
+ ty = sem::Type::Common({existing, ty});
+ if (ty) {
+ res.first->second = ty;
+ }
+ return ty;
}
- /// If the number with index `idx` is open, then it is closed with number
- /// `number` and Num() returns true. If the number is closed, then `Num()`
- /// returns true iff it is equal to `ty`.
- bool Num(uint32_t idx, Number number) {
+ /// If the number with index `idx` is undefined, then it is defined with the number `number` and
+ /// Num() returns true. If the number is defined, then `Num()` returns true iff it is equal to
+ /// `ty`.
+ bool Num(size_t idx, Number number) {
auto res = numbers_.emplace(idx, number.Value());
return res.second || res.first->second == number.Value();
}
- /// Type returns the closed type with index `idx`.
- /// An ICE is raised if the type is not closed.
- const sem::Type* Type(uint32_t idx) const {
+ /// Type returns the template type with index `idx`, or nullptr if the type was not defined.
+ const sem::Type* Type(size_t idx) const {
auto it = types_.find(idx);
- if (it == types_.end()) {
- TINT_ICE(Resolver, builder.Diagnostics())
- << "type with index " << idx << " is not closed";
- return nullptr;
- }
- TINT_ASSERT(Resolver, it != types_.end());
- return it->second;
+ return (it != types_.end()) ? it->second : nullptr;
}
+ /// SetType replaces the template type with index `idx` with type `ty`.
+ void SetType(size_t idx, const sem::Type* ty) { types_[idx] = ty; }
+
/// Type returns the number type with index `idx`.
- /// An ICE is raised if the number is not closed.
- Number Num(uint32_t idx) const {
+ Number Num(size_t idx) const {
auto it = numbers_.find(idx);
- if (it == numbers_.end()) {
- TINT_ICE(Resolver, builder.Diagnostics())
- << "number with index " << idx << " is not closed";
- return Number::invalid;
- }
- return Number(it->second);
+ return (it != numbers_.end()) ? Number(it->second) : Number::invalid;
}
private:
- ProgramBuilder& builder;
- std::unordered_map<uint32_t, const sem::Type*> types_;
- std::unordered_map<uint32_t, uint32_t> numbers_;
+ std::unordered_map<size_t, const sem::Type*> types_;
+ std::unordered_map<size_t, uint32_t> numbers_;
};
/// Index type used for matcher indices
using MatcherIndex = uint8_t;
-/// Index value used for open types / numbers that do not have a constraint
+/// Index value used for template types / numbers that do not have a constraint
constexpr MatcherIndex kNoMatcher = std::numeric_limits<MatcherIndex>::max();
/// MatchState holds the state used to match an overload.
class MatchState {
public:
MatchState(ProgramBuilder& b,
- ClosedState& c,
+ TemplateState& t,
const Matchers& m,
- const OverloadInfo& o,
+ const OverloadInfo* o,
MatcherIndex const* matcher_indices)
- : builder(b), closed(c), matchers(m), overload(o), matcher_indices_(matcher_indices) {}
+ : builder(b), templates(t), matchers(m), overload(o), matcher_indices_(matcher_indices) {}
/// The program builder
ProgramBuilder& builder;
- /// The open / closed types and numbers
- ClosedState& closed;
+ /// The template types and numbers
+ TemplateState& templates;
/// The type and number matchers
Matchers const& matchers;
/// The current overload being evaluated
- OverloadInfo const& overload;
+ OverloadInfo const* overload;
/// Type uses the next TypeMatcher from the matcher indices to match the type
/// `ty`. If the type matches, the canonical expected type is returned. If the
@@ -211,14 +219,14 @@
/// Checks whether the given type matches the matcher rules, and returns the
/// expected, canonicalized type on success.
- /// Match may close open types and numbers in state.
+ /// Match may define and refine the template types and numbers in state.
/// @param type the type to match
/// @returns the canonicalized type on match, otherwise nullptr
virtual const sem::Type* Match(MatchState& state, const sem::Type* type) const = 0;
/// @return a string representation of the matcher. Used for printing error
/// messages when no overload is found.
- virtual std::string String(MatchState& state) const = 0;
+ virtual std::string String(MatchState* state) const = 0;
};
/// A NumberMatcher is the interface used to match a number or enumerator used
@@ -229,55 +237,58 @@
virtual ~NumberMatcher() = default;
/// Checks whether the given number matches the matcher rules.
- /// Match may close open numbers in state.
+ /// Match may define template numbers in state.
/// @param number the number to match
/// @returns true if the argument type is as expected.
virtual Number Match(MatchState& state, Number number) const = 0;
/// @return a string representation of the matcher. Used for printing error
/// messages when no overload is found.
- virtual std::string String(MatchState& state) const = 0;
+ virtual std::string String(MatchState* state) const = 0;
};
-/// OpenTypeMatcher is a Matcher for an open type.
-/// The OpenTypeMatcher will match against any type (so long as it is consistent
-/// across all uses in the overload)
-class OpenTypeMatcher : public TypeMatcher {
+/// TemplateTypeMatcher is a Matcher for a template type.
+/// The TemplateTypeMatcher will initially match against any type, and then will only be further
+/// constrained based on the conversion rules defined at https://www.w3.org/TR/WGSL/#conversion-rank
+class TemplateTypeMatcher : public TypeMatcher {
public:
/// Constructor
- explicit OpenTypeMatcher(uint32_t index) : index_(index) {}
+ explicit TemplateTypeMatcher(size_t index) : index_(index) {}
const sem::Type* Match(MatchState& state, const sem::Type* type) const override {
if (type->Is<Any>()) {
- return state.closed.Type(index_);
+ return state.templates.Type(index_);
}
- return state.closed.Type(index_, type) ? type : nullptr;
+ if (auto* templates = state.templates.Type(index_, type)) {
+ return templates;
+ }
+ return nullptr;
}
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
private:
- uint32_t index_;
+ size_t index_;
};
-/// OpenNumberMatcher is a Matcher for an open number.
-/// The OpenNumberMatcher will match against any number (so long as it is
-/// consistent for the overload)
-class OpenNumberMatcher : public NumberMatcher {
+/// TemplateNumberMatcher is a Matcher for a template number.
+/// The TemplateNumberMatcher will match against any number (so long as it is
+/// consistent for all uses in the overload)
+class TemplateNumberMatcher : public NumberMatcher {
public:
- explicit OpenNumberMatcher(uint32_t index) : index_(index) {}
+ explicit TemplateNumberMatcher(size_t index) : index_(index) {}
Number Match(MatchState& state, Number number) const override {
if (number.IsAny()) {
- return state.closed.Num(index_);
+ return state.templates.Num(index_);
}
- return state.closed.Num(index_, number) ? number : Number::invalid;
+ return state.templates.Num(index_, number) ? number : Number::invalid;
}
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
private:
- uint32_t index_;
+ size_t index_;
};
////////////////////////////////////////////////////////////////////////////////
@@ -289,19 +300,53 @@
using Access = ast::Access;
using StorageClass = ast::StorageClass;
using ParameterUsage = sem::ParameterUsage;
-using PipelineStageSet = sem::PipelineStageSet;
using PipelineStage = ast::PipelineStage;
+/// Unique flag bits for overloads
+enum class OverloadFlag {
+ kIsBuiltin, // The overload is a builtin ('fn')
+ kIsOperator, // The overload is an operator ('op')
+ kIsConstructor, // The overload is a type constructor ('ctor')
+ kIsConverter, // The overload is a type converter ('conv')
+ kSupportsVertexPipeline, // The overload can be used in vertex shaders
+ kSupportsFragmentPipeline, // The overload can be used in fragment shaders
+ kSupportsComputePipeline, // The overload can be used in compute shaders
+ kIsDeprecated, // The overload is deprecated
+};
+
+// An enum set of OverloadFlag, used by OperatorInfo
+using OverloadFlags = utils::EnumSet<OverloadFlag>;
+
bool match_bool(const sem::Type* ty) {
return ty->IsAnyOf<Any, sem::Bool>();
}
+const sem::AbstractFloat* build_af(MatchState& state) {
+ return state.builder.create<sem::AbstractFloat>();
+}
+
+bool match_af(const sem::Type* ty) {
+ return ty->IsAnyOf<Any, sem::AbstractFloat>();
+}
+
+const sem::AbstractInt* build_ai(MatchState& state) {
+ return state.builder.create<sem::AbstractInt>();
+}
+
+bool match_ai(const sem::Type* ty) {
+ return ty->IsAnyOf<Any, sem::AbstractInt>();
+}
+
const sem::Bool* build_bool(MatchState& state) {
return state.builder.create<sem::Bool>();
}
+const sem::F32* build_f32(MatchState& state) {
+ return state.builder.create<sem::F32>();
+}
+
bool match_f32(const sem::Type* ty) {
- return ty->IsAnyOf<Any, sem::F32>();
+ return ty->IsAnyOf<Any, sem::F32, sem::AbstractNumeric>();
}
const sem::I32* build_i32(MatchState& state) {
@@ -309,7 +354,7 @@
}
bool match_i32(const sem::Type* ty) {
- return ty->IsAnyOf<Any, sem::I32>();
+ return ty->IsAnyOf<Any, sem::I32, sem::AbstractInt>();
}
const sem::U32* build_u32(MatchState& state) {
@@ -317,11 +362,7 @@
}
bool match_u32(const sem::Type* ty) {
- return ty->IsAnyOf<Any, sem::U32>();
-}
-
-const sem::F32* build_f32(MatchState& state) {
- return state.builder.create<sem::F32>();
+ return ty->IsAnyOf<Any, sem::U32, sem::AbstractInt>();
}
bool match_vec(const sem::Type* ty, Number& N, const sem::Type*& T) {
@@ -339,11 +380,7 @@
return false;
}
-const sem::Vector* build_vec(MatchState& state, Number N, const sem::Type* el) {
- return state.builder.create<sem::Vector>(el, N.Value());
-}
-
-template <int N>
+template <uint32_t N>
bool match_vec(const sem::Type* ty, const sem::Type*& T) {
if (ty->Is<Any>()) {
T = ty;
@@ -359,29 +396,22 @@
return false;
}
-bool match_vec2(const sem::Type* ty, const sem::Type*& T) {
- return match_vec<2>(ty, T);
+const sem::Vector* build_vec(MatchState& state, Number N, const sem::Type* el) {
+ return state.builder.create<sem::Vector>(el, N.Value());
}
-const sem::Vector* build_vec2(MatchState& state, const sem::Type* T) {
- return build_vec(state, Number(2), T);
+template <uint32_t N>
+const sem::Vector* build_vec(MatchState& state, const sem::Type* el) {
+ return state.builder.create<sem::Vector>(el, N);
}
-bool match_vec3(const sem::Type* ty, const sem::Type*& T) {
- return match_vec<3>(ty, T);
-}
+constexpr auto match_vec2 = match_vec<2>;
+constexpr auto match_vec3 = match_vec<3>;
+constexpr auto match_vec4 = match_vec<4>;
-const sem::Vector* build_vec3(MatchState& state, const sem::Type* T) {
- return build_vec(state, Number(3), T);
-}
-
-bool match_vec4(const sem::Type* ty, const sem::Type*& T) {
- return match_vec<4>(ty, T);
-}
-
-const sem::Vector* build_vec4(MatchState& state, const sem::Type* T) {
- return build_vec(state, Number(4), T);
-}
+constexpr auto build_vec2 = build_vec<2>;
+constexpr auto build_vec3 = build_vec<3>;
+constexpr auto build_vec4 = build_vec<4>;
bool match_mat(const sem::Type* ty, Number& M, Number& N, const sem::Type*& T) {
if (ty->Is<Any>()) {
@@ -399,11 +429,52 @@
return false;
}
-const sem::Matrix* build_mat(MatchState& state, Number N, Number M, const sem::Type* T) {
- auto* column_type = state.builder.create<sem::Vector>(T, M.Value());
- return state.builder.create<sem::Matrix>(column_type, N.Value());
+template <uint32_t C, uint32_t R>
+bool match_mat(const sem::Type* ty, const sem::Type*& T) {
+ if (ty->Is<Any>()) {
+ T = ty;
+ return true;
+ }
+ if (auto* m = ty->As<sem::Matrix>()) {
+ if (m->columns() == C && m->rows() == R) {
+ T = m->type();
+ return true;
+ }
+ }
+ return false;
}
+const sem::Matrix* build_mat(MatchState& state, Number C, Number R, const sem::Type* T) {
+ auto* column_type = state.builder.create<sem::Vector>(T, R.Value());
+ return state.builder.create<sem::Matrix>(column_type, C.Value());
+}
+
+template <uint32_t C, uint32_t R>
+const sem::Matrix* build_mat(MatchState& state, const sem::Type* T) {
+ auto* column_type = state.builder.create<sem::Vector>(T, R);
+ return state.builder.create<sem::Matrix>(column_type, C);
+}
+
+constexpr auto build_mat2x2 = build_mat<2, 2>;
+constexpr auto build_mat2x3 = build_mat<2, 3>;
+constexpr auto build_mat2x4 = build_mat<2, 4>;
+constexpr auto build_mat3x2 = build_mat<3, 2>;
+constexpr auto build_mat3x3 = build_mat<3, 3>;
+constexpr auto build_mat3x4 = build_mat<3, 4>;
+constexpr auto build_mat4x2 = build_mat<4, 2>;
+constexpr auto build_mat4x3 = build_mat<4, 3>;
+constexpr auto build_mat4x4 = build_mat<4, 4>;
+
+constexpr auto match_mat2x2 = match_mat<2, 2>;
+constexpr auto match_mat2x3 = match_mat<2, 3>;
+constexpr auto match_mat2x4 = match_mat<2, 4>;
+constexpr auto match_mat3x2 = match_mat<3, 2>;
+constexpr auto match_mat3x3 = match_mat<3, 3>;
+constexpr auto match_mat3x4 = match_mat<3, 4>;
+constexpr auto match_mat4x2 = match_mat<4, 2>;
+constexpr auto match_mat4x3 = match_mat<4, 3>;
+constexpr auto match_mat4x4 = match_mat<4, 4>;
+
bool match_array(const sem::Type* ty, const sem::Type*& T) {
if (ty->Is<Any>()) {
T = ty;
@@ -720,18 +791,18 @@
MatcherIndex const* const matcher_indices;
};
-/// OpenTypeInfo describes an open type
-struct OpenTypeInfo {
- /// Name of the open type (e.g. 'T')
+/// TemplateTypeInfo describes an template type
+struct TemplateTypeInfo {
+ /// Name of the template type (e.g. 'T')
const char* name;
/// Optional type matcher constraint.
/// Either an index in Matchers::type, or kNoMatcher
const MatcherIndex matcher_index;
};
-/// OpenNumberInfo describes an open number
-struct OpenNumberInfo {
- /// Name of the open number (e.g. 'N')
+/// TemplateNumberInfo describes a template number
+struct TemplateNumberInfo {
+ /// Name of the template number (e.g. 'N')
const char* name;
/// Optional number matcher constraint.
/// Either an index in Matchers::number, or kNoMatcher
@@ -742,24 +813,22 @@
struct OverloadInfo {
/// Total number of parameters for the overload
const uint8_t num_parameters;
- /// Total number of open types for the overload
- const uint8_t num_open_types;
- /// Total number of open numbers for the overload
- const uint8_t num_open_numbers;
- /// Pointer to the first open type
- OpenTypeInfo const* const open_types;
- /// Pointer to the first open number
- OpenNumberInfo const* const open_numbers;
+ /// Total number of template types for the overload
+ const uint8_t num_template_types;
+ /// Total number of template numbers for the overload
+ const uint8_t num_template_numbers;
+ /// Pointer to the first template type
+ TemplateTypeInfo const* const template_types;
+ /// Pointer to the first template number
+ TemplateNumberInfo const* const template_numbers;
/// Pointer to the first parameter
ParameterInfo const* const parameters;
/// Pointer to a list of matcher indices that index on Matchers::type and
/// Matchers::number, used to build the return type. If the function has no
/// return type then this is null
MatcherIndex const* const return_matcher_indices;
- /// The pipeline stages that this overload can be used in
- PipelineStageSet supported_stages;
- /// True if the overload is marked as deprecated
- bool is_deprecated;
+ /// The flags for the overload
+ OverloadFlags flags;
};
/// IntrinsicInfo describes a builtin function or operator overload
@@ -791,21 +860,18 @@
for (auto& p : i.parameters) {
utils::HashCombine(&hash, p.type, p.usage);
}
- return utils::Hash(hash, i.index, i.return_type, i.supported_stages, i.is_deprecated);
+ return utils::Hash(hash, i.overload, i.return_type);
}
};
- uint32_t index = 0; // Index of the intrinsic (builtin or operator)
- std::vector<Parameter> parameters;
+ const OverloadInfo* overload = nullptr;
sem::Type const* return_type = nullptr;
- PipelineStageSet supported_stages;
- bool is_deprecated = false;
+ std::vector<Parameter> parameters;
};
/// Equality operator for IntrinsicPrototype
bool operator==(const IntrinsicPrototype& a, const IntrinsicPrototype& b) {
- if (a.index != b.index || a.supported_stages != b.supported_stages ||
- a.return_type != b.return_type || a.is_deprecated != b.is_deprecated ||
+ if (a.overload != b.overload || a.return_type != b.return_type ||
a.parameters.size() != b.parameters.size()) {
return false;
}
@@ -836,38 +902,108 @@
const Source& source,
bool is_compound) override;
+ const sem::CallTarget* Lookup(CtorConvIntrinsic type,
+ const sem::Type* template_arg,
+ const std::vector<const sem::Type*>& args,
+ const Source& source) override;
+
private:
- // Candidate holds information about a mismatched overload that could be what the user intended
- // to call.
+ /// Candidate holds information about an overload evaluated for resolution.
struct Candidate {
+ /// The candidate overload
const OverloadInfo* overload;
- int score;
+ /// The template types and numbers
+ TemplateState templates;
+ /// The parameter types for the candidate overload
+ std::vector<IntrinsicPrototype::Parameter> parameters;
+ /// The match-score of the candidate overload.
+ /// A score of zero indicates an exact match.
+ /// Non-zero scores are used for diagnostics when no overload matches.
+ /// Lower scores are displayed first (top-most).
+ size_t score;
};
- const IntrinsicPrototype Match(const char* intrinsic_name,
- uint32_t intrinsic_index,
- const OverloadInfo& overload,
- const std::vector<const sem::Type*>& args,
- int& match_score);
+ /// A list of candidates
+ using Candidates = std::vector<Candidate>;
- MatchState Match(ClosedState& closed,
- const OverloadInfo& overload,
+ /// Callback function when no overloads match.
+ using OnNoMatch = std::function<void(Candidates)>;
+
+ /// Attempts to find a single intrinsic overload that matches the provided argument types.
+ /// @param intrinsic the intrinsic being called
+ /// @param intrinsic_name the name of the intrinsic
+ /// @param args the argument types
+ /// @param templates initial template state. This may contain explicitly specified template
+ /// arguments. For example `vec3<f32>()` would have the first template-type
+ /// defined as `f32`.
+ /// @param on_no_match an error callback when no intrinsic overloads matched the provided
+ /// arguments.
+ /// @returns the matched intrinsic. If no intrinsic could be matched then IntrinsicPrototype
+ /// will hold nullptrs for IntrinsicPrototype::overload and
+ /// IntrinsicPrototype::return_type.
+ IntrinsicPrototype MatchIntrinsic(const IntrinsicInfo& intrinsic,
+ const char* intrinsic_name,
+ const std::vector<const sem::Type*>& args,
+ TemplateState templates,
+ OnNoMatch on_no_match) const;
+
+ /// Evaluates the overload for the provided argument types.
+ /// @param overload the overload being considered
+ /// @param args the argument types
+ /// @param templates initial template state. This may contain explicitly specified template
+ /// arguments. For example `vec3<f32>()` would have the first template-type
+ /// template as `f32`.
+ /// @returns the evaluated Candidate information.
+ Candidate ScoreOverload(const OverloadInfo* overload,
+ const std::vector<const sem::Type*>& args,
+ TemplateState templates) const;
+
+ /// Match constructs a new MatchState
+ /// @param templates the template state used for matcher evaluation
+ /// @param overload the overload being evaluated
+ /// @param matcher_indices pointer to a list of matcher indices
+ MatchState Match(TemplateState& templates,
+ const OverloadInfo* overload,
MatcherIndex const* matcher_indices) const;
- void PrintOverload(std::ostream& ss, const OverloadInfo& overload, const char* name) const;
+ // Prints the overload for emitting diagnostics
+ void PrintOverload(std::ostream& ss,
+ const OverloadInfo* overload,
+ const char* intrinsic_name) const;
+
+ // Prints the list of candidates for emitting diagnostics
+ void PrintCandidates(std::ostream& ss,
+ const Candidates& candidates,
+ const char* intrinsic_name) const;
+
+ /// Raises an ICE when multiple overload candidates match, as this should never happen.
+ void ErrMultipleOverloadsMatched(size_t num_matched,
+ const char* intrinsic_name,
+ const std::vector<const sem::Type*>& args,
+ TemplateState templates,
+ Candidates candidates) const;
ProgramBuilder& builder;
Matchers matchers;
std::unordered_map<IntrinsicPrototype, sem::Builtin*, IntrinsicPrototype::Hasher> builtins;
+ std::unordered_map<IntrinsicPrototype, sem::TypeConstructor*, IntrinsicPrototype::Hasher>
+ constructors;
+ std::unordered_map<IntrinsicPrototype, sem::TypeConversion*, IntrinsicPrototype::Hasher>
+ converters;
};
/// @return a string representing a call to a builtin with the given argument
/// types.
std::string CallSignature(ProgramBuilder& builder,
const char* intrinsic_name,
- const std::vector<const sem::Type*>& args) {
+ const std::vector<const sem::Type*>& args,
+ const sem::Type* template_arg = nullptr) {
std::stringstream ss;
- ss << intrinsic_name << "(";
+ ss << intrinsic_name;
+ if (template_arg) {
+ ss << "<" << template_arg->FriendlyName(builder.Symbols()) << ">";
+ }
+ ss << "(";
{
bool first = true;
for (auto* arg : args) {
@@ -883,12 +1019,12 @@
return ss.str();
}
-std::string OpenTypeMatcher::String(MatchState& state) const {
- return state.overload.open_types[index_].name;
+std::string TemplateTypeMatcher::String(MatchState* state) const {
+ return state->overload->template_types[index_].name;
}
-std::string OpenNumberMatcher::String(MatchState& state) const {
- return state.overload.open_numbers[index_].name;
+std::string TemplateNumberMatcher::String(MatchState* state) const {
+ return state->overload->template_numbers[index_].name;
}
Impl::Impl(ProgramBuilder& b) : builder(b) {}
@@ -896,110 +1032,90 @@
const sem::Builtin* Impl::Lookup(sem::BuiltinType builtin_type,
const std::vector<const sem::Type*>& args,
const Source& source) {
- // The list of failed matches that had promise.
- std::vector<Candidate> candidates;
-
- uint32_t intrinsic_index = static_cast<uint32_t>(builtin_type);
const char* intrinsic_name = sem::str(builtin_type);
- auto& builtin = kBuiltins[intrinsic_index];
- for (uint32_t o = 0; o < builtin.num_overloads; o++) {
- int match_score = 1000;
- auto& overload = builtin.overloads[o];
- auto match = Match(intrinsic_name, intrinsic_index, overload, args, match_score);
- if (match.return_type) {
- // De-duplicate builtins that are identical.
- return utils::GetOrCreate(builtins, match, [&] {
- std::vector<sem::Parameter*> params;
- params.reserve(match.parameters.size());
- for (auto& p : match.parameters) {
- params.emplace_back(builder.create<sem::Parameter>(
- nullptr, static_cast<uint32_t>(params.size()), p.type,
- ast::StorageClass::kNone, ast::Access::kUndefined, p.usage));
- }
- return builder.create<sem::Builtin>(builtin_type, match.return_type,
- std::move(params), match.supported_stages,
- match.is_deprecated);
- });
+
+ // Generates an error when no overloads match the provided arguments
+ auto on_no_match = [&](Candidates candidates) {
+ std::stringstream ss;
+ ss << "no matching call to " << CallSignature(builder, intrinsic_name, args) << std::endl;
+ if (!candidates.empty()) {
+ ss << std::endl
+ << candidates.size() << " candidate function" << (candidates.size() > 1 ? "s:" : ":")
+ << std::endl;
+ PrintCandidates(ss, candidates, intrinsic_name);
}
- if (match_score > 0) {
- candidates.emplace_back(Candidate{&overload, match_score});
- }
+ builder.Diagnostics().add_error(diag::System::Resolver, ss.str(), source);
+ };
+
+ // Resolve the intrinsic overload
+ auto match = MatchIntrinsic(kBuiltins[static_cast<size_t>(builtin_type)], intrinsic_name, args,
+ TemplateState{}, on_no_match);
+ if (!match.overload) {
+ return {};
}
- // Sort the candidates with the most promising first
- std::stable_sort(candidates.begin(), candidates.end(),
- [](const Candidate& a, const Candidate& b) { return a.score > b.score; });
-
- // Generate an error message
- std::stringstream ss;
- ss << "no matching call to " << CallSignature(builder, intrinsic_name, args) << std::endl;
- if (!candidates.empty()) {
- ss << std::endl;
- ss << candidates.size() << " candidate function" << (candidates.size() > 1 ? "s:" : ":")
- << std::endl;
- for (auto& candidate : candidates) {
- ss << " ";
- PrintOverload(ss, *candidate.overload, intrinsic_name);
- ss << std::endl;
+ // De-duplicate builtins that are identical.
+ return utils::GetOrCreate(builtins, match, [&] {
+ std::vector<sem::Parameter*> params;
+ params.reserve(match.parameters.size());
+ for (auto& p : match.parameters) {
+ params.emplace_back(builder.create<sem::Parameter>(
+ nullptr, static_cast<uint32_t>(params.size()), p.type, ast::StorageClass::kNone,
+ ast::Access::kUndefined, p.usage));
}
- }
- builder.Diagnostics().add_error(diag::System::Resolver, ss.str(), source);
- return nullptr;
+ sem::PipelineStageSet supported_stages;
+ if (match.overload->flags.Contains(OverloadFlag::kSupportsVertexPipeline)) {
+ supported_stages.Add(ast::PipelineStage::kVertex);
+ }
+ if (match.overload->flags.Contains(OverloadFlag::kSupportsFragmentPipeline)) {
+ supported_stages.Add(ast::PipelineStage::kFragment);
+ }
+ if (match.overload->flags.Contains(OverloadFlag::kSupportsComputePipeline)) {
+ supported_stages.Add(ast::PipelineStage::kCompute);
+ }
+ return builder.create<sem::Builtin>(
+ builtin_type, match.return_type, std::move(params), supported_stages,
+ match.overload->flags.Contains(OverloadFlag::kIsDeprecated));
+ });
}
IntrinsicTable::UnaryOperator Impl::Lookup(ast::UnaryOp op,
const sem::Type* arg,
const Source& source) {
- // The list of failed matches that had promise.
- std::vector<Candidate> candidates;
-
- auto [intrinsic_index, intrinsic_name] = [&]() -> std::pair<uint32_t, const char*> {
+ auto [intrinsic_index, intrinsic_name] = [&]() -> std::pair<size_t, const char*> {
switch (op) {
case ast::UnaryOp::kComplement:
- return {kOperatorComplement, "operator ~ "};
+ return {kUnaryOperatorComplement, "operator ~ "};
case ast::UnaryOp::kNegation:
- return {kOperatorMinus, "operator - "};
+ return {kUnaryOperatorMinus, "operator - "};
case ast::UnaryOp::kNot:
- return {kOperatorNot, "operator ! "};
+ return {kUnaryOperatorNot, "operator ! "};
default:
return {0, "<unknown>"};
}
}();
- auto& builtin = kOperators[intrinsic_index];
- for (uint32_t o = 0; o < builtin.num_overloads; o++) {
- int match_score = 1000;
- auto& overload = builtin.overloads[o];
- if (overload.num_parameters == 1) {
- auto match = Match(intrinsic_name, intrinsic_index, overload, {arg}, match_score);
- if (match.return_type) {
- return UnaryOperator{match.return_type, match.parameters[0].type};
- }
- if (match_score > 0) {
- candidates.emplace_back(Candidate{&overload, match_score});
- }
+ // Generates an error when no overloads match the provided arguments
+ auto on_no_match = [&, name = intrinsic_name](Candidates candidates) {
+ std::stringstream ss;
+ ss << "no matching overload for " << CallSignature(builder, name, {arg}) << std::endl;
+ if (!candidates.empty()) {
+ ss << std::endl
+ << candidates.size() << " candidate operator" << (candidates.size() > 1 ? "s:" : ":")
+ << std::endl;
+ PrintCandidates(ss, candidates, name);
}
+ builder.Diagnostics().add_error(diag::System::Resolver, ss.str(), source);
+ };
+
+ // Resolve the intrinsic overload
+ auto match = MatchIntrinsic(kUnaryOperators[intrinsic_index], intrinsic_name, {arg},
+ TemplateState{}, on_no_match);
+ if (!match.overload) {
+ return {};
}
- // Sort the candidates with the most promising first
- std::stable_sort(candidates.begin(), candidates.end(),
- [](const Candidate& a, const Candidate& b) { return a.score > b.score; });
-
- // Generate an error message
- std::stringstream ss;
- ss << "no matching overload for " << CallSignature(builder, intrinsic_name, {arg}) << std::endl;
- if (!candidates.empty()) {
- ss << std::endl;
- ss << candidates.size() << " candidate operator" << (candidates.size() > 1 ? "s:" : ":")
- << std::endl;
- for (auto& candidate : candidates) {
- ss << " ";
- PrintOverload(ss, *candidate.overload, intrinsic_name);
- ss << std::endl;
- }
- }
- builder.Diagnostics().add_error(diag::System::Resolver, ss.str(), source);
- return {};
+ return UnaryOperator{match.return_type, match.parameters[0].type};
}
IntrinsicTable::BinaryOperator Impl::Lookup(ast::BinaryOp op,
@@ -1007,200 +1123,305 @@
const sem::Type* rhs,
const Source& source,
bool is_compound) {
- // The list of failed matches that had promise.
- std::vector<Candidate> candidates;
-
- auto [intrinsic_index, intrinsic_name] = [&]() -> std::pair<uint32_t, const char*> {
+ auto [intrinsic_index, intrinsic_name] = [&]() -> std::pair<size_t, const char*> {
switch (op) {
case ast::BinaryOp::kAnd:
- return {kOperatorAnd, is_compound ? "operator &= " : "operator & "};
+ return {kBinaryOperatorAnd, is_compound ? "operator &= " : "operator & "};
case ast::BinaryOp::kOr:
- return {kOperatorOr, is_compound ? "operator |= " : "operator | "};
+ return {kBinaryOperatorOr, is_compound ? "operator |= " : "operator | "};
case ast::BinaryOp::kXor:
- return {kOperatorXor, is_compound ? "operator ^= " : "operator ^ "};
+ return {kBinaryOperatorXor, is_compound ? "operator ^= " : "operator ^ "};
case ast::BinaryOp::kLogicalAnd:
- return {kOperatorLogicalAnd, "operator && "};
+ return {kBinaryOperatorLogicalAnd, "operator && "};
case ast::BinaryOp::kLogicalOr:
- return {kOperatorLogicalOr, "operator || "};
+ return {kBinaryOperatorLogicalOr, "operator || "};
case ast::BinaryOp::kEqual:
- return {kOperatorEqual, "operator == "};
+ return {kBinaryOperatorEqual, "operator == "};
case ast::BinaryOp::kNotEqual:
- return {kOperatorNotEqual, "operator != "};
+ return {kBinaryOperatorNotEqual, "operator != "};
case ast::BinaryOp::kLessThan:
- return {kOperatorLessThan, "operator < "};
+ return {kBinaryOperatorLessThan, "operator < "};
case ast::BinaryOp::kGreaterThan:
- return {kOperatorGreaterThan, "operator > "};
+ return {kBinaryOperatorGreaterThan, "operator > "};
case ast::BinaryOp::kLessThanEqual:
- return {kOperatorLessThanEqual, "operator <= "};
+ return {kBinaryOperatorLessThanEqual, "operator <= "};
case ast::BinaryOp::kGreaterThanEqual:
- return {kOperatorGreaterThanEqual, "operator >= "};
+ return {kBinaryOperatorGreaterThanEqual, "operator >= "};
case ast::BinaryOp::kShiftLeft:
- return {kOperatorShiftLeft, is_compound ? "operator <<= " : "operator << "};
+ return {kBinaryOperatorShiftLeft, is_compound ? "operator <<= " : "operator << "};
case ast::BinaryOp::kShiftRight:
- return {kOperatorShiftRight, is_compound ? "operator >>= " : "operator >> "};
+ return {kBinaryOperatorShiftRight, is_compound ? "operator >>= " : "operator >> "};
case ast::BinaryOp::kAdd:
- return {kOperatorPlus, is_compound ? "operator += " : "operator + "};
+ return {kBinaryOperatorPlus, is_compound ? "operator += " : "operator + "};
case ast::BinaryOp::kSubtract:
- return {kOperatorMinus, is_compound ? "operator -= " : "operator - "};
+ return {kBinaryOperatorMinus, is_compound ? "operator -= " : "operator - "};
case ast::BinaryOp::kMultiply:
- return {kOperatorStar, is_compound ? "operator *= " : "operator * "};
+ return {kBinaryOperatorStar, is_compound ? "operator *= " : "operator * "};
case ast::BinaryOp::kDivide:
- return {kOperatorDivide, is_compound ? "operator /= " : "operator / "};
+ return {kBinaryOperatorDivide, is_compound ? "operator /= " : "operator / "};
case ast::BinaryOp::kModulo:
- return {kOperatorModulo, is_compound ? "operator %= " : "operator % "};
+ return {kBinaryOperatorModulo, is_compound ? "operator %= " : "operator % "};
default:
return {0, "<unknown>"};
}
}();
- auto& builtin = kOperators[intrinsic_index];
- for (uint32_t o = 0; o < builtin.num_overloads; o++) {
- int match_score = 1000;
- auto& overload = builtin.overloads[o];
- if (overload.num_parameters == 2) {
- auto match = Match(intrinsic_name, intrinsic_index, overload, {lhs, rhs}, match_score);
- if (match.return_type) {
- return BinaryOperator{match.return_type, match.parameters[0].type,
- match.parameters[1].type};
- }
- if (match_score > 0) {
- candidates.emplace_back(Candidate{&overload, match_score});
+ // Generates an error when no overloads match the provided arguments
+ auto on_no_match = [&, name = intrinsic_name](Candidates candidates) {
+ std::stringstream ss;
+ ss << "no matching overload for " << CallSignature(builder, name, {lhs, rhs}) << std::endl;
+ if (!candidates.empty()) {
+ ss << std::endl
+ << candidates.size() << " candidate operator" << (candidates.size() > 1 ? "s:" : ":")
+ << std::endl;
+ PrintCandidates(ss, candidates, name);
+ }
+ builder.Diagnostics().add_error(diag::System::Resolver, ss.str(), source);
+ };
+
+ // Resolve the intrinsic overload
+ auto match = MatchIntrinsic(kBinaryOperators[intrinsic_index], intrinsic_name, {lhs, rhs},
+ TemplateState{}, on_no_match);
+ if (!match.overload) {
+ return {};
+ }
+
+ return BinaryOperator{match.return_type, match.parameters[0].type, match.parameters[1].type};
+}
+
+const sem::CallTarget* Impl::Lookup(CtorConvIntrinsic type,
+ const sem::Type* template_arg,
+ const std::vector<const sem::Type*>& args,
+ const Source& source) {
+ auto name = str(type);
+
+ // Generates an error when no overloads match the provided arguments
+ auto on_no_match = [&](Candidates candidates) {
+ std::stringstream ss;
+ ss << "no matching constructor for " << CallSignature(builder, name, args, template_arg)
+ << std::endl;
+ Candidates ctor, conv;
+ for (auto candidate : candidates) {
+ if (candidate.overload->flags.Contains(OverloadFlag::kIsConstructor)) {
+ ctor.emplace_back(candidate);
+ } else {
+ conv.emplace_back(candidate);
}
}
+ if (!ctor.empty()) {
+ ss << std::endl
+ << ctor.size() << " candidate constructor" << (ctor.size() > 1 ? "s:" : ":")
+ << std::endl;
+ PrintCandidates(ss, ctor, name);
+ }
+ if (!conv.empty()) {
+ ss << std::endl
+ << conv.size() << " candidate conversion" << (conv.size() > 1 ? "s:" : ":")
+ << std::endl;
+ PrintCandidates(ss, conv, name);
+ }
+ builder.Diagnostics().add_error(diag::System::Resolver, ss.str(), source);
+ };
+
+ // If a template type was provided, then close the 0'th type with this.
+ TemplateState templates;
+ if (template_arg) {
+ templates.Type(0, template_arg);
+ }
+
+ // Resolve the intrinsic overload
+ auto match = MatchIntrinsic(kConstructorsAndConverters[static_cast<size_t>(type)], name, args,
+ templates, on_no_match);
+ if (!match.overload) {
+ return {};
+ }
+
+ // Was this overload a constructor or conversion?
+ if (match.overload->flags.Contains(OverloadFlag::kIsConstructor)) {
+ sem::ParameterList params;
+ params.reserve(match.parameters.size());
+ for (auto& p : match.parameters) {
+ params.emplace_back(builder.create<sem::Parameter>(
+ nullptr, static_cast<uint32_t>(params.size()), p.type, ast::StorageClass::kNone,
+ ast::Access::kUndefined, p.usage));
+ }
+ return utils::GetOrCreate(constructors, match, [&]() {
+ return builder.create<sem::TypeConstructor>(match.return_type, std::move(params));
+ });
+ }
+
+ // 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);
+ return builder.create<sem::TypeConversion>(match.return_type, param);
+ });
+}
+
+IntrinsicPrototype Impl::MatchIntrinsic(const IntrinsicInfo& intrinsic,
+ const char* intrinsic_name,
+ const std::vector<const sem::Type*>& args,
+ TemplateState templates,
+ OnNoMatch on_no_match) const {
+ size_t num_matched = 0;
+ Candidates candidates;
+ candidates.reserve(intrinsic.num_overloads);
+ for (size_t overload_idx = 0; overload_idx < static_cast<size_t>(intrinsic.num_overloads);
+ overload_idx++) {
+ auto candidate = ScoreOverload(&intrinsic.overloads[overload_idx], args, templates);
+ if (candidate.score == 0) {
+ num_matched++;
+ }
+ candidates.emplace_back(std::move(candidate));
}
// Sort the candidates with the most promising first
std::stable_sort(candidates.begin(), candidates.end(),
- [](const Candidate& a, const Candidate& b) { return a.score > b.score; });
+ [&](const Candidate& a, const Candidate& b) { return a.score < b.score; });
- // Generate an error message
- std::stringstream ss;
- ss << "no matching overload for " << CallSignature(builder, intrinsic_name, {lhs, rhs})
- << std::endl;
- if (!candidates.empty()) {
- ss << std::endl;
- ss << candidates.size() << " candidate operator" << (candidates.size() > 1 ? "s:" : ":")
- << std::endl;
- for (auto& candidate : candidates) {
- ss << " ";
- PrintOverload(ss, *candidate.overload, intrinsic_name);
- ss << std::endl;
- }
- }
- builder.Diagnostics().add_error(diag::System::Resolver, ss.str(), source);
- return {};
-}
-
-const IntrinsicPrototype Impl::Match(const char* intrinsic_name,
- uint32_t intrinsic_index,
- const OverloadInfo& overload,
- const std::vector<const sem::Type*>& args,
- int& match_score) {
- // Score wait for argument <-> parameter count matches / mismatches
- constexpr int kScorePerParamArgMismatch = -1;
- constexpr int kScorePerMatchedParam = 2;
- constexpr int kScorePerMatchedOpenType = 1;
- constexpr int kScorePerMatchedOpenNumber = 1;
-
- auto num_parameters = overload.num_parameters;
- auto num_arguments = static_cast<decltype(num_parameters)>(args.size());
-
- bool overload_matched = true;
-
- if (num_parameters != num_arguments) {
- match_score += kScorePerParamArgMismatch * (std::max(num_parameters, num_arguments) -
- std::min(num_parameters, num_arguments));
- overload_matched = false;
+ // How many candidates matched?
+ switch (num_matched) {
+ case 0:
+ on_no_match(std::move(candidates));
+ return {};
+ case 1:
+ break;
+ default:
+ // Note: Currently the intrinsic table does not contain any overloads which may result
+ // in ambiguities, so here we call ErrMultipleOverloadsMatched() which will produce and
+ // ICE. If we end up in the situation where this is unavoidable, we'll need to perform
+ // further overload resolution as described in
+ // https://www.w3.org/TR/WGSL/#overload-resolution-section.
+ ErrMultipleOverloadsMatched(num_matched, intrinsic_name, args, templates, candidates);
}
- ClosedState closed(builder);
-
- std::vector<IntrinsicPrototype::Parameter> parameters;
-
- auto num_params = std::min(num_parameters, num_arguments);
- for (uint32_t p = 0; p < num_params; p++) {
- auto& parameter = overload.parameters[p];
- auto* indices = parameter.matcher_indices;
- auto* type = Match(closed, overload, indices).Type(args[p]->UnwrapRef());
- if (type) {
- parameters.emplace_back(IntrinsicPrototype::Parameter{type, parameter.usage});
- match_score += kScorePerMatchedParam;
- } else {
- overload_matched = false;
- }
- }
-
- if (overload_matched) {
- // Check all constrained open types matched
- for (uint32_t ot = 0; ot < overload.num_open_types; ot++) {
- auto& open_type = overload.open_types[ot];
- if (open_type.matcher_index != kNoMatcher) {
- auto* index = &open_type.matcher_index;
- if (Match(closed, overload, index).Type(closed.Type(ot))) {
- match_score += kScorePerMatchedOpenType;
- } else {
- overload_matched = false;
- }
- }
- }
- }
-
- if (overload_matched) {
- // Check all constrained open numbers matched
- for (uint32_t on = 0; on < overload.num_open_numbers; on++) {
- auto& open_number = overload.open_numbers[on];
- if (open_number.matcher_index != kNoMatcher) {
- auto* index = &open_number.matcher_index;
- if (Match(closed, overload, index).Num(closed.Num(on)).IsValid()) {
- match_score += kScorePerMatchedOpenNumber;
- } else {
- overload_matched = false;
- }
- }
- }
- }
-
- if (!overload_matched) {
- return {};
- }
+ auto match = candidates[0];
// Build the return type
const sem::Type* return_type = nullptr;
- if (auto* indices = overload.return_matcher_indices) {
+ if (auto* indices = match.overload->return_matcher_indices) {
Any any;
- return_type = Match(closed, overload, indices).Type(&any);
+ return_type = Match(match.templates, match.overload, indices).Type(&any);
if (!return_type) {
- std::stringstream ss;
- PrintOverload(ss, overload, intrinsic_name);
- TINT_ICE(Resolver, builder.Diagnostics())
- << "MatchState.Match() returned null for " << ss.str();
+ TINT_ICE(Resolver, builder.Diagnostics()) << "MatchState.Match() returned null";
return {};
}
} else {
return_type = builder.create<sem::Void>();
}
- IntrinsicPrototype builtin;
- builtin.index = intrinsic_index;
- builtin.return_type = return_type;
- builtin.parameters = std::move(parameters);
- builtin.supported_stages = overload.supported_stages;
- builtin.is_deprecated = overload.is_deprecated;
- return builtin;
+ return IntrinsicPrototype{match.overload, return_type, std::move(match.parameters)};
}
-MatchState Impl::Match(ClosedState& closed,
- const OverloadInfo& overload,
+Impl::Candidate Impl::ScoreOverload(const OverloadInfo* overload,
+ const std::vector<const sem::Type*>& args,
+ TemplateState templates) const {
+ // Penalty weights for overload mismatching.
+ // This scoring is used to order the suggested overloads in diagnostic on overload mismatch, and
+ // has no impact for a correct program.
+ // The overloads with the lowest score will be displayed first (top-most).
+ constexpr int kMismatchedParamCountPenalty = 3;
+ constexpr int kMismatchedParamTypePenalty = 2;
+ constexpr int kMismatchedTemplateTypePenalty = 1;
+ constexpr int kMismatchedTemplateNumberPenalty = 1;
+
+ size_t num_parameters = static_cast<size_t>(overload->num_parameters);
+ size_t num_arguments = static_cast<size_t>(args.size());
+
+ size_t score = 0;
+
+ if (num_parameters != num_arguments) {
+ score += kMismatchedParamCountPenalty * (std::max(num_parameters, num_arguments) -
+ std::min(num_parameters, num_arguments));
+ }
+
+ // Invoke the matchers for each parameter <-> argument pair.
+ // If any arguments cannot be matched, then `score` will be increased.
+ // If the overload has any template types or numbers then these will be set based on the
+ // argument types. Template types may be refined by constraining with later argument types. For
+ // example calling `F<T>(T, T)` with the argument types (abstract-int, i32) will first set T to
+ // abstract-int when matching the first argument, and then constrained down to i32 when matching
+ // the second argument.
+ // Note that inferred template types are not tested against their matchers at this point.
+ auto num_params = std::min(num_parameters, num_arguments);
+ for (size_t p = 0; p < num_params; p++) {
+ auto& parameter = overload->parameters[p];
+ auto* indices = parameter.matcher_indices;
+ if (!Match(templates, overload, indices).Type(args[p]->UnwrapRef())) {
+ score += kMismatchedParamTypePenalty;
+ }
+ }
+
+ if (score == 0) {
+ // Check all constrained template types matched their constraint matchers.
+ // If the template type *does not* match any of the types in the constraint matcher, then
+ // `score` is incremented. If the template type *does* match a type, then the template type
+ // is replaced with the first matching type. The order of types in the template matcher is
+ // important here, which can be controlled with the [[precedence(N)]] decorations on the
+ // types in intrinsics.def.
+ for (size_t ot = 0; ot < overload->num_template_types; ot++) {
+ auto* matcher_index = &overload->template_types[ot].matcher_index;
+ if (*matcher_index != kNoMatcher) {
+ if (auto* template_type = templates.Type(ot)) {
+ if (auto* ty = Match(templates, overload, matcher_index).Type(template_type)) {
+ // Template type matched one of the types in the template type's matcher.
+ // Replace the template type with this type.
+ templates.SetType(ot, ty);
+ continue;
+ }
+ }
+ score += kMismatchedTemplateTypePenalty;
+ }
+ }
+ }
+
+ if (score == 0) {
+ // Check all constrained open numbers matched.
+ // Unlike template types, numbers are not constrained, so we're just checking that the
+ // inferred number matches the constraints on the overload. Increments `score` if the
+ // template numbers do not match their constraint matchers.
+ for (size_t on = 0; on < overload->num_template_numbers; on++) {
+ auto* matcher_index = &overload->template_numbers[on].matcher_index;
+ if (*matcher_index != kNoMatcher) {
+ auto template_num = templates.Num(on);
+ if (!template_num.IsValid() ||
+ !Match(templates, overload, matcher_index).Num(template_num).IsValid()) {
+ score += kMismatchedTemplateNumberPenalty;
+ }
+ }
+ }
+ }
+
+ // Now that all the template types have been finalized, we can construct the parameters.
+ std::vector<IntrinsicPrototype::Parameter> parameters;
+ if (score == 0) {
+ parameters.reserve(num_params);
+ for (size_t p = 0; p < num_params; p++) {
+ auto& parameter = overload->parameters[p];
+ auto* indices = parameter.matcher_indices;
+ auto* ty = Match(templates, overload, indices).Type(args[p]->UnwrapRef());
+ parameters.emplace_back(IntrinsicPrototype::Parameter{ty, parameter.usage});
+ }
+ }
+
+ return Candidate{overload, templates, parameters, score};
+}
+
+MatchState Impl::Match(TemplateState& templates,
+ const OverloadInfo* overload,
MatcherIndex const* matcher_indices) const {
- return MatchState(builder, closed, matchers, overload, matcher_indices);
+ return MatchState(builder, templates, matchers, overload, matcher_indices);
}
-void Impl::PrintOverload(std::ostream& ss, const OverloadInfo& overload, const char* name) const {
- ClosedState closed(builder);
+void Impl::PrintOverload(std::ostream& ss,
+ const OverloadInfo* overload,
+ const char* intrinsic_name) const {
+ TemplateState templates;
- ss << name << "(";
- for (uint32_t p = 0; p < overload.num_parameters; p++) {
- auto& parameter = overload.parameters[p];
+ ss << intrinsic_name << "(";
+ for (size_t p = 0; p < overload->num_parameters; p++) {
+ auto& parameter = overload->parameters[p];
if (p > 0) {
ss << ", ";
}
@@ -1208,13 +1429,13 @@
ss << sem::str(parameter.usage) << ": ";
}
auto* indices = parameter.matcher_indices;
- ss << Match(closed, overload, indices).TypeName();
+ ss << Match(templates, overload, indices).TypeName();
}
ss << ")";
- if (overload.return_matcher_indices) {
+ if (overload->return_matcher_indices) {
ss << " -> ";
- auto* indices = overload.return_matcher_indices;
- ss << Match(closed, overload, indices).TypeName();
+ auto* indices = overload->return_matcher_indices;
+ ss << Match(templates, overload, indices).TypeName();
}
bool first = true;
@@ -1222,26 +1443,36 @@
ss << (first ? " where: " : ", ");
first = false;
};
- for (uint32_t i = 0; i < overload.num_open_types; i++) {
- auto& open_type = overload.open_types[i];
- if (open_type.matcher_index != kNoMatcher) {
+ for (size_t i = 0; i < overload->num_template_types; i++) {
+ auto& template_type = overload->template_types[i];
+ if (template_type.matcher_index != kNoMatcher) {
separator();
- ss << open_type.name;
- auto* index = &open_type.matcher_index;
- ss << " is " << Match(closed, overload, index).TypeName();
+ ss << template_type.name;
+ auto* index = &template_type.matcher_index;
+ ss << " is " << Match(templates, overload, index).TypeName();
}
}
- for (uint32_t i = 0; i < overload.num_open_numbers; i++) {
- auto& open_number = overload.open_numbers[i];
- if (open_number.matcher_index != kNoMatcher) {
+ for (size_t i = 0; i < overload->num_template_numbers; i++) {
+ auto& template_number = overload->template_numbers[i];
+ if (template_number.matcher_index != kNoMatcher) {
separator();
- ss << open_number.name;
- auto* index = &open_number.matcher_index;
- ss << " is " << Match(closed, overload, index).NumName();
+ ss << template_number.name;
+ auto* index = &template_number.matcher_index;
+ ss << " is " << Match(templates, overload, index).NumName();
}
}
}
+void Impl::PrintCandidates(std::ostream& ss,
+ const Candidates& candidates,
+ const char* intrinsic_name) const {
+ for (auto& candidate : candidates) {
+ ss << " ";
+ PrintOverload(ss, candidate.overload, intrinsic_name);
+ ss << std::endl;
+ }
+}
+
const sem::Type* MatchState::Type(const sem::Type* ty) {
MatcherIndex matcher_index = *matcher_indices_++;
auto* matcher = matchers.type[matcher_index];
@@ -1257,13 +1488,50 @@
std::string MatchState::TypeName() {
MatcherIndex matcher_index = *matcher_indices_++;
auto* matcher = matchers.type[matcher_index];
- return matcher->String(*this);
+ return matcher->String(this);
}
std::string MatchState::NumName() {
MatcherIndex matcher_index = *matcher_indices_++;
auto* matcher = matchers.number[matcher_index];
- return matcher->String(*this);
+ return matcher->String(this);
+}
+
+void Impl::ErrMultipleOverloadsMatched(size_t num_matched,
+ const char* intrinsic_name,
+ const std::vector<const sem::Type*>& args,
+ TemplateState templates,
+ Candidates candidates) const {
+ std::stringstream ss;
+ ss << num_matched << " overloads matched " << intrinsic_name;
+ for (size_t i = 0; i < std::numeric_limits<size_t>::max(); i++) {
+ if (auto* ty = templates.Type(i)) {
+ ss << ((i == 0) ? "<" : ", ") << ty->FriendlyName(builder.Symbols());
+ } else {
+ if (i > 0) {
+ ss << ">";
+ }
+ break;
+ }
+ }
+ ss << "(";
+ bool first = true;
+ for (auto* arg : args) {
+ if (!first) {
+ ss << ", ";
+ }
+ first = false;
+ ss << arg->FriendlyName(builder.Symbols());
+ }
+ ss << "):\n";
+ for (auto& candidate : candidates) {
+ if (candidate.score == 0) {
+ ss << " ";
+ PrintOverload(ss, candidate.overload, intrinsic_name);
+ ss << std::endl;
+ }
+ }
+ TINT_ICE(Resolver, builder.Diagnostics()) << ss.str();
}
} // namespace
@@ -1274,7 +1542,7 @@
IntrinsicTable::~IntrinsicTable() = default;
-/// TypeInfo for the Any type declared in the anonymous namespace above
-TINT_INSTANTIATE_TYPEINFO(Any);
+} // namespace tint::resolver
-} // namespace tint
+/// TypeInfo for the Any type declared in the anonymous namespace above
+TINT_INSTANTIATE_TYPEINFO(tint::resolver::Any);
diff --git a/src/tint/resolver/intrinsic_table.h b/src/tint/resolver/intrinsic_table.h
index e873202..5a8985f 100644
--- a/src/tint/resolver/intrinsic_table.h
+++ b/src/tint/resolver/intrinsic_table.h
@@ -19,6 +19,7 @@
#include <string>
#include <vector>
+#include "src/tint/resolver/ctor_conv_intrinsic.h"
#include "src/tint/sem/builtin.h"
// Forward declarations
@@ -26,7 +27,7 @@
class ProgramBuilder;
} // namespace tint
-namespace tint {
+namespace tint::resolver {
/// IntrinsicTable is a lookup table of all the WGSL builtin functions and intrinsic operators
class IntrinsicTable {
@@ -89,8 +90,20 @@
const sem::Type* rhs,
const Source& source,
bool is_compound) = 0;
+
+ /// Lookup looks for the type constructor or conversion overload for the given
+ /// CtorConvIntrinsic.
+ /// @param type the type being constructed or converted
+ /// @param template_arg the optional template argument
+ /// @param args the argument types passed to the constructor / conversion call
+ /// @param source the source of the call
+ /// @return a sem::TypeConstructor, sem::TypeConversion or nullptr if nothing matched
+ virtual const sem::CallTarget* Lookup(CtorConvIntrinsic type,
+ const sem::Type* template_arg,
+ const std::vector<const sem::Type*>& args,
+ const Source& source) = 0;
};
-} // namespace tint
+} // namespace tint::resolver
#endif // SRC_TINT_RESOLVER_INTRINSIC_TABLE_H_
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl
index 9981bb8..c518e58 100644
--- a/src/tint/resolver/intrinsic_table.inl
+++ b/src/tint/resolver/intrinsic_table.inl
@@ -25,11 +25,11 @@
// clang-format off
/// TypeMatcher for 'type bool'
-/// @see src/tint/intrinsics.def:68:6
+/// @see src/tint/intrinsics.def:73:6
class Bool : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -37,7 +37,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Bool::Match(MatchState& state, const sem::Type* ty) const {
@@ -47,16 +47,16 @@
return build_bool(state);
}
-std::string Bool::String(MatchState&) const {
+std::string Bool::String(MatchState*) const {
return "bool";
}
-/// TypeMatcher for 'type f32'
-/// @see src/tint/intrinsics.def:69:6
-class F32 : public TypeMatcher {
+/// TypeMatcher for 'type af'
+/// @see src/tint/intrinsics.def:74:51
+class Af : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -64,26 +64,57 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
-const sem::Type* F32::Match(MatchState& state, const sem::Type* ty) const {
- if (!match_f32(ty)) {
+const sem::Type* Af::Match(MatchState& state, const sem::Type* ty) const {
+ if (!match_af(ty)) {
return nullptr;
}
- return build_f32(state);
+ return build_af(state);
}
-std::string F32::String(MatchState&) const {
- return "f32";
+std::string Af::String(MatchState*) const {
+ std::stringstream ss;
+ ss << "abstract-float";
+ return ss.str();
+}
+
+/// TypeMatcher for 'type ai'
+/// @see src/tint/intrinsics.def:75:51
+class Ai : 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* Ai::Match(MatchState& state, const sem::Type* ty) const {
+ if (!match_ai(ty)) {
+ return nullptr;
+ }
+ return build_ai(state);
+}
+
+std::string Ai::String(MatchState*) const {
+ std::stringstream ss;
+ ss << "abstract-int";
+ return ss.str();
}
/// TypeMatcher for 'type i32'
-/// @see src/tint/intrinsics.def:70:6
+/// @see src/tint/intrinsics.def:76:24
class I32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -91,7 +122,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* I32::Match(MatchState& state, const sem::Type* ty) const {
@@ -101,16 +132,16 @@
return build_i32(state);
}
-std::string I32::String(MatchState&) const {
+std::string I32::String(MatchState*) const {
return "i32";
}
/// TypeMatcher for 'type u32'
-/// @see src/tint/intrinsics.def:71:6
+/// @see src/tint/intrinsics.def:77:24
class U32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -118,7 +149,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* U32::Match(MatchState& state, const sem::Type* ty) const {
@@ -128,16 +159,16 @@
return build_u32(state);
}
-std::string U32::String(MatchState&) const {
+std::string U32::String(MatchState*) const {
return "u32";
}
-/// TypeMatcher for 'type vec2'
-/// @see src/tint/intrinsics.def:72:6
-class Vec2 : public TypeMatcher {
+/// TypeMatcher for 'type f32'
+/// @see src/tint/intrinsics.def:78:24
+class F32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -145,7 +176,34 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
+};
+
+const sem::Type* F32::Match(MatchState& state, const sem::Type* ty) const {
+ if (!match_f32(ty)) {
+ return nullptr;
+ }
+ return build_f32(state);
+}
+
+std::string F32::String(MatchState*) const {
+ return "f32";
+}
+
+/// TypeMatcher for 'type vec2'
+/// @see src/tint/intrinsics.def:79:6
+class Vec2 : 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* Vec2::Match(MatchState& state, const sem::Type* ty) const {
@@ -160,17 +218,17 @@
return build_vec2(state, T);
}
-std::string Vec2::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string Vec2::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "vec2<" + T + ">";
}
/// TypeMatcher for 'type vec3'
-/// @see src/tint/intrinsics.def:73:6
+/// @see src/tint/intrinsics.def:80:6
class Vec3 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -178,7 +236,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Vec3::Match(MatchState& state, const sem::Type* ty) const {
@@ -193,17 +251,17 @@
return build_vec3(state, T);
}
-std::string Vec3::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string Vec3::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "vec3<" + T + ">";
}
/// TypeMatcher for 'type vec4'
-/// @see src/tint/intrinsics.def:74:6
+/// @see src/tint/intrinsics.def:81:6
class Vec4 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -211,7 +269,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Vec4::Match(MatchState& state, const sem::Type* ty) const {
@@ -226,17 +284,17 @@
return build_vec4(state, T);
}
-std::string Vec4::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string Vec4::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "vec4<" + T + ">";
}
-/// TypeMatcher for 'type vec'
-/// @see src/tint/intrinsics.def:75:37
-class Vec : public TypeMatcher {
+/// TypeMatcher for 'type mat2x2'
+/// @see src/tint/intrinsics.def:82:6
+class Mat2X2 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -244,7 +302,304 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
+};
+
+const sem::Type* Mat2X2::Match(MatchState& state, const sem::Type* ty) const {
+ const sem::Type* T = nullptr;
+ if (!match_mat2x2(ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat2x2(state, T);
+}
+
+std::string Mat2X2::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ return "mat2x2<" + T + ">";
+}
+
+/// TypeMatcher for 'type mat2x3'
+/// @see src/tint/intrinsics.def:83:6
+class Mat2X3 : 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* Mat2X3::Match(MatchState& state, const sem::Type* ty) const {
+ const sem::Type* T = nullptr;
+ if (!match_mat2x3(ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat2x3(state, T);
+}
+
+std::string Mat2X3::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ return "mat2x3<" + T + ">";
+}
+
+/// TypeMatcher for 'type mat2x4'
+/// @see src/tint/intrinsics.def:84:6
+class Mat2X4 : 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* Mat2X4::Match(MatchState& state, const sem::Type* ty) const {
+ const sem::Type* T = nullptr;
+ if (!match_mat2x4(ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat2x4(state, T);
+}
+
+std::string Mat2X4::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ return "mat2x4<" + T + ">";
+}
+
+/// TypeMatcher for 'type mat3x2'
+/// @see src/tint/intrinsics.def:85:6
+class Mat3X2 : 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* Mat3X2::Match(MatchState& state, const sem::Type* ty) const {
+ const sem::Type* T = nullptr;
+ if (!match_mat3x2(ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat3x2(state, T);
+}
+
+std::string Mat3X2::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ return "mat3x2<" + T + ">";
+}
+
+/// TypeMatcher for 'type mat3x3'
+/// @see src/tint/intrinsics.def:86:6
+class Mat3X3 : 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* Mat3X3::Match(MatchState& state, const sem::Type* ty) const {
+ const sem::Type* T = nullptr;
+ if (!match_mat3x3(ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat3x3(state, T);
+}
+
+std::string Mat3X3::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ return "mat3x3<" + T + ">";
+}
+
+/// TypeMatcher for 'type mat3x4'
+/// @see src/tint/intrinsics.def:87:6
+class Mat3X4 : 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* Mat3X4::Match(MatchState& state, const sem::Type* ty) const {
+ const sem::Type* T = nullptr;
+ if (!match_mat3x4(ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat3x4(state, T);
+}
+
+std::string Mat3X4::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ return "mat3x4<" + T + ">";
+}
+
+/// TypeMatcher for 'type mat4x2'
+/// @see src/tint/intrinsics.def:88:6
+class Mat4X2 : 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* Mat4X2::Match(MatchState& state, const sem::Type* ty) const {
+ const sem::Type* T = nullptr;
+ if (!match_mat4x2(ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat4x2(state, T);
+}
+
+std::string Mat4X2::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ return "mat4x2<" + T + ">";
+}
+
+/// TypeMatcher for 'type mat4x3'
+/// @see src/tint/intrinsics.def:89:6
+class Mat4X3 : 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* Mat4X3::Match(MatchState& state, const sem::Type* ty) const {
+ const sem::Type* T = nullptr;
+ if (!match_mat4x3(ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat4x3(state, T);
+}
+
+std::string Mat4X3::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ return "mat4x3<" + T + ">";
+}
+
+/// TypeMatcher for 'type mat4x4'
+/// @see src/tint/intrinsics.def:90:6
+class Mat4X4 : 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* Mat4X4::Match(MatchState& state, const sem::Type* ty) const {
+ const sem::Type* T = nullptr;
+ if (!match_mat4x4(ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat4x4(state, T);
+}
+
+std::string Mat4X4::String(MatchState* state) const {
+ const std::string T = state->TypeName();
+ return "mat4x4<" + T + ">";
+}
+
+/// TypeMatcher for 'type vec'
+/// @see src/tint/intrinsics.def:91:37
+class Vec : 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* Vec::Match(MatchState& state, const sem::Type* ty) const {
@@ -264,20 +619,20 @@
return build_vec(state, N, T);
}
-std::string Vec::String(MatchState& state) const {
- const std::string N = state.NumName();
- const std::string T = state.TypeName();
+std::string Vec::String(MatchState* state) const {
+ const std::string N = state->NumName();
+ const std::string T = state->TypeName();
std::stringstream ss;
ss << "vec" << N << "<" << T << ">";
return ss.str();
}
/// TypeMatcher for 'type mat'
-/// @see src/tint/intrinsics.def:76:37
+/// @see src/tint/intrinsics.def:92:37
class Mat : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -285,7 +640,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Mat::Match(MatchState& state, const sem::Type* ty) const {
@@ -310,21 +665,21 @@
return build_mat(state, N, M, T);
}
-std::string Mat::String(MatchState& state) const {
- const std::string N = state.NumName();
- const std::string M = state.NumName();
- const std::string T = state.TypeName();
+std::string Mat::String(MatchState* state) const {
+ const std::string N = state->NumName();
+ const std::string M = state->NumName();
+ const std::string T = state->TypeName();
std::stringstream ss;
ss << "mat" << N << "x" << M << "<" << T << ">";
return ss.str();
}
/// TypeMatcher for 'type ptr'
-/// @see src/tint/intrinsics.def:77:6
+/// @see src/tint/intrinsics.def:93:6
class Ptr : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -332,7 +687,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Ptr::Match(MatchState& state, const sem::Type* ty) const {
@@ -357,19 +712,19 @@
return build_ptr(state, S, T, A);
}
-std::string Ptr::String(MatchState& state) const {
- const std::string S = state.NumName();
- const std::string T = state.TypeName();
- const std::string A = state.NumName();
+std::string Ptr::String(MatchState* state) const {
+ const std::string S = state->NumName();
+ const std::string T = state->TypeName();
+ const std::string A = state->NumName();
return "ptr<" + S + ", " + T + ", " + A + ">";
}
/// TypeMatcher for 'type atomic'
-/// @see src/tint/intrinsics.def:78:6
+/// @see src/tint/intrinsics.def:94:6
class Atomic : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -377,7 +732,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Atomic::Match(MatchState& state, const sem::Type* ty) const {
@@ -392,17 +747,17 @@
return build_atomic(state, T);
}
-std::string Atomic::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string Atomic::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "atomic<" + T + ">";
}
/// TypeMatcher for 'type array'
-/// @see src/tint/intrinsics.def:79:6
+/// @see src/tint/intrinsics.def:95:6
class Array : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -410,7 +765,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Array::Match(MatchState& state, const sem::Type* ty) const {
@@ -425,17 +780,17 @@
return build_array(state, T);
}
-std::string Array::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string Array::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "array<" + T + ">";
}
/// TypeMatcher for 'type sampler'
-/// @see src/tint/intrinsics.def:80:6
+/// @see src/tint/intrinsics.def:96:6
class Sampler : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -443,7 +798,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Sampler::Match(MatchState& state, const sem::Type* ty) const {
@@ -453,16 +808,16 @@
return build_sampler(state);
}
-std::string Sampler::String(MatchState&) const {
+std::string Sampler::String(MatchState*) const {
return "sampler";
}
/// TypeMatcher for 'type sampler_comparison'
-/// @see src/tint/intrinsics.def:81:6
+/// @see src/tint/intrinsics.def:97:6
class SamplerComparison : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -470,7 +825,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* SamplerComparison::Match(MatchState& state, const sem::Type* ty) const {
@@ -480,16 +835,16 @@
return build_sampler_comparison(state);
}
-std::string SamplerComparison::String(MatchState&) const {
+std::string SamplerComparison::String(MatchState*) const {
return "sampler_comparison";
}
/// TypeMatcher for 'type texture_1d'
-/// @see src/tint/intrinsics.def:82:6
+/// @see src/tint/intrinsics.def:98:6
class Texture1D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -497,7 +852,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Texture1D::Match(MatchState& state, const sem::Type* ty) const {
@@ -512,17 +867,17 @@
return build_texture_1d(state, T);
}
-std::string Texture1D::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string Texture1D::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "texture_1d<" + T + ">";
}
/// TypeMatcher for 'type texture_2d'
-/// @see src/tint/intrinsics.def:83:6
+/// @see src/tint/intrinsics.def:99:6
class Texture2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -530,7 +885,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Texture2D::Match(MatchState& state, const sem::Type* ty) const {
@@ -545,17 +900,17 @@
return build_texture_2d(state, T);
}
-std::string Texture2D::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string Texture2D::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "texture_2d<" + T + ">";
}
/// TypeMatcher for 'type texture_2d_array'
-/// @see src/tint/intrinsics.def:84:6
+/// @see src/tint/intrinsics.def:100:6
class Texture2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -563,7 +918,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Texture2DArray::Match(MatchState& state, const sem::Type* ty) const {
@@ -578,17 +933,17 @@
return build_texture_2d_array(state, T);
}
-std::string Texture2DArray::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string Texture2DArray::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "texture_2d_array<" + T + ">";
}
/// TypeMatcher for 'type texture_3d'
-/// @see src/tint/intrinsics.def:85:6
+/// @see src/tint/intrinsics.def:101:6
class Texture3D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -596,7 +951,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Texture3D::Match(MatchState& state, const sem::Type* ty) const {
@@ -611,17 +966,17 @@
return build_texture_3d(state, T);
}
-std::string Texture3D::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string Texture3D::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "texture_3d<" + T + ">";
}
/// TypeMatcher for 'type texture_cube'
-/// @see src/tint/intrinsics.def:86:6
+/// @see src/tint/intrinsics.def:102:6
class TextureCube : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -629,7 +984,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureCube::Match(MatchState& state, const sem::Type* ty) const {
@@ -644,17 +999,17 @@
return build_texture_cube(state, T);
}
-std::string TextureCube::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string TextureCube::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "texture_cube<" + T + ">";
}
/// TypeMatcher for 'type texture_cube_array'
-/// @see src/tint/intrinsics.def:87:6
+/// @see src/tint/intrinsics.def:103:6
class TextureCubeArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -662,7 +1017,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureCubeArray::Match(MatchState& state, const sem::Type* ty) const {
@@ -677,17 +1032,17 @@
return build_texture_cube_array(state, T);
}
-std::string TextureCubeArray::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string TextureCubeArray::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "texture_cube_array<" + T + ">";
}
/// TypeMatcher for 'type texture_multisampled_2d'
-/// @see src/tint/intrinsics.def:88:6
+/// @see src/tint/intrinsics.def:104:6
class TextureMultisampled2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -695,7 +1050,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureMultisampled2D::Match(MatchState& state, const sem::Type* ty) const {
@@ -710,17 +1065,17 @@
return build_texture_multisampled_2d(state, T);
}
-std::string TextureMultisampled2D::String(MatchState& state) const {
- const std::string T = state.TypeName();
+std::string TextureMultisampled2D::String(MatchState* state) const {
+ const std::string T = state->TypeName();
return "texture_multisampled_2d<" + T + ">";
}
/// TypeMatcher for 'type texture_depth_2d'
-/// @see src/tint/intrinsics.def:89:6
+/// @see src/tint/intrinsics.def:105:6
class TextureDepth2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -728,7 +1083,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureDepth2D::Match(MatchState& state, const sem::Type* ty) const {
@@ -738,16 +1093,16 @@
return build_texture_depth_2d(state);
}
-std::string TextureDepth2D::String(MatchState&) const {
+std::string TextureDepth2D::String(MatchState*) const {
return "texture_depth_2d";
}
/// TypeMatcher for 'type texture_depth_2d_array'
-/// @see src/tint/intrinsics.def:90:6
+/// @see src/tint/intrinsics.def:106:6
class TextureDepth2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -755,7 +1110,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureDepth2DArray::Match(MatchState& state, const sem::Type* ty) const {
@@ -765,16 +1120,16 @@
return build_texture_depth_2d_array(state);
}
-std::string TextureDepth2DArray::String(MatchState&) const {
+std::string TextureDepth2DArray::String(MatchState*) const {
return "texture_depth_2d_array";
}
/// TypeMatcher for 'type texture_depth_cube'
-/// @see src/tint/intrinsics.def:91:6
+/// @see src/tint/intrinsics.def:107:6
class TextureDepthCube : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -782,7 +1137,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureDepthCube::Match(MatchState& state, const sem::Type* ty) const {
@@ -792,16 +1147,16 @@
return build_texture_depth_cube(state);
}
-std::string TextureDepthCube::String(MatchState&) const {
+std::string TextureDepthCube::String(MatchState*) const {
return "texture_depth_cube";
}
/// TypeMatcher for 'type texture_depth_cube_array'
-/// @see src/tint/intrinsics.def:92:6
+/// @see src/tint/intrinsics.def:108:6
class TextureDepthCubeArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -809,7 +1164,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureDepthCubeArray::Match(MatchState& state, const sem::Type* ty) const {
@@ -819,16 +1174,16 @@
return build_texture_depth_cube_array(state);
}
-std::string TextureDepthCubeArray::String(MatchState&) const {
+std::string TextureDepthCubeArray::String(MatchState*) const {
return "texture_depth_cube_array";
}
/// TypeMatcher for 'type texture_depth_multisampled_2d'
-/// @see src/tint/intrinsics.def:93:6
+/// @see src/tint/intrinsics.def:109:6
class TextureDepthMultisampled2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -836,7 +1191,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureDepthMultisampled2D::Match(MatchState& state, const sem::Type* ty) const {
@@ -846,16 +1201,16 @@
return build_texture_depth_multisampled_2d(state);
}
-std::string TextureDepthMultisampled2D::String(MatchState&) const {
+std::string TextureDepthMultisampled2D::String(MatchState*) const {
return "texture_depth_multisampled_2d";
}
/// TypeMatcher for 'type texture_storage_1d'
-/// @see src/tint/intrinsics.def:94:6
+/// @see src/tint/intrinsics.def:110:6
class TextureStorage1D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -863,7 +1218,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureStorage1D::Match(MatchState& state, const sem::Type* ty) const {
@@ -883,18 +1238,18 @@
return build_texture_storage_1d(state, F, A);
}
-std::string TextureStorage1D::String(MatchState& state) const {
- const std::string F = state.NumName();
- const std::string A = state.NumName();
+std::string TextureStorage1D::String(MatchState* state) const {
+ const std::string F = state->NumName();
+ const std::string A = state->NumName();
return "texture_storage_1d<" + F + ", " + A + ">";
}
/// TypeMatcher for 'type texture_storage_2d'
-/// @see src/tint/intrinsics.def:95:6
+/// @see src/tint/intrinsics.def:111:6
class TextureStorage2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -902,7 +1257,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureStorage2D::Match(MatchState& state, const sem::Type* ty) const {
@@ -922,18 +1277,18 @@
return build_texture_storage_2d(state, F, A);
}
-std::string TextureStorage2D::String(MatchState& state) const {
- const std::string F = state.NumName();
- const std::string A = state.NumName();
+std::string TextureStorage2D::String(MatchState* state) const {
+ const std::string F = state->NumName();
+ const std::string A = state->NumName();
return "texture_storage_2d<" + F + ", " + A + ">";
}
/// TypeMatcher for 'type texture_storage_2d_array'
-/// @see src/tint/intrinsics.def:96:6
+/// @see src/tint/intrinsics.def:112:6
class TextureStorage2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -941,7 +1296,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureStorage2DArray::Match(MatchState& state, const sem::Type* ty) const {
@@ -961,18 +1316,18 @@
return build_texture_storage_2d_array(state, F, A);
}
-std::string TextureStorage2DArray::String(MatchState& state) const {
- const std::string F = state.NumName();
- const std::string A = state.NumName();
+std::string TextureStorage2DArray::String(MatchState* state) const {
+ const std::string F = state->NumName();
+ const std::string A = state->NumName();
return "texture_storage_2d_array<" + F + ", " + A + ">";
}
/// TypeMatcher for 'type texture_storage_3d'
-/// @see src/tint/intrinsics.def:97:6
+/// @see src/tint/intrinsics.def:113:6
class TextureStorage3D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -980,7 +1335,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureStorage3D::Match(MatchState& state, const sem::Type* ty) const {
@@ -1000,18 +1355,18 @@
return build_texture_storage_3d(state, F, A);
}
-std::string TextureStorage3D::String(MatchState& state) const {
- const std::string F = state.NumName();
- const std::string A = state.NumName();
+std::string TextureStorage3D::String(MatchState* state) const {
+ const std::string F = state->NumName();
+ const std::string A = state->NumName();
return "texture_storage_3d<" + F + ", " + A + ">";
}
/// TypeMatcher for 'type texture_external'
-/// @see src/tint/intrinsics.def:98:6
+/// @see src/tint/intrinsics.def:114:6
class TextureExternal : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -1019,7 +1374,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* TextureExternal::Match(MatchState& state, const sem::Type* ty) const {
@@ -1029,16 +1384,16 @@
return build_texture_external(state);
}
-std::string TextureExternal::String(MatchState&) const {
+std::string TextureExternal::String(MatchState*) const {
return "texture_external";
}
/// TypeMatcher for 'type __modf_result'
-/// @see src/tint/intrinsics.def:100:6
+/// @see src/tint/intrinsics.def:116:6
class ModfResult : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -1046,7 +1401,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* ModfResult::Match(MatchState& state, const sem::Type* ty) const {
@@ -1056,16 +1411,16 @@
return build_modf_result(state);
}
-std::string ModfResult::String(MatchState&) const {
+std::string ModfResult::String(MatchState*) const {
return "__modf_result";
}
/// TypeMatcher for 'type __modf_result_vec'
-/// @see src/tint/intrinsics.def:101:42
+/// @see src/tint/intrinsics.def:117:42
class ModfResultVec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -1073,7 +1428,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* ModfResultVec::Match(MatchState& state, const sem::Type* ty) const {
@@ -1088,19 +1443,19 @@
return build_modf_result_vec(state, N);
}
-std::string ModfResultVec::String(MatchState& state) const {
- const std::string N = state.NumName();
+std::string ModfResultVec::String(MatchState* state) const {
+ const std::string N = state->NumName();
std::stringstream ss;
ss << "__modf_result_vec" << N;
return ss.str();
}
/// TypeMatcher for 'type __frexp_result'
-/// @see src/tint/intrinsics.def:102:6
+/// @see src/tint/intrinsics.def:118:6
class FrexpResult : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -1108,7 +1463,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* FrexpResult::Match(MatchState& state, const sem::Type* ty) const {
@@ -1118,16 +1473,16 @@
return build_frexp_result(state);
}
-std::string FrexpResult::String(MatchState&) const {
+std::string FrexpResult::String(MatchState*) const {
return "__frexp_result";
}
/// TypeMatcher for 'type __frexp_result_vec'
-/// @see src/tint/intrinsics.def:103:43
+/// @see src/tint/intrinsics.def:119:43
class FrexpResultVec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -1135,7 +1490,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* FrexpResultVec::Match(MatchState& state, const sem::Type* ty) const {
@@ -1150,20 +1505,20 @@
return build_frexp_result_vec(state, N);
}
-std::string FrexpResultVec::String(MatchState& state) const {
- const std::string N = state.NumName();
+std::string FrexpResultVec::String(MatchState* state) const {
+ const std::string N = state->NumName();
std::stringstream ss;
ss << "__frexp_result_vec" << N;
return ss.str();
}
/// TypeMatcher for 'match fiu32'
-/// @see src/tint/intrinsics.def:111:7
+/// @see src/tint/intrinsics.def:127:7
class Fiu32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
/// expected, canonicalized type on success.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -1171,33 +1526,37 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Fiu32::Match(MatchState& state, const sem::Type* ty) const {
- if (match_f32(ty)) {
- return build_f32(state);
- }
if (match_i32(ty)) {
return build_i32(state);
}
if (match_u32(ty)) {
return build_u32(state);
}
+ if (match_f32(ty)) {
+ return build_f32(state);
+ }
return nullptr;
}
-std::string Fiu32::String(MatchState&) const {
- return "f32, i32 or u32";
+std::string Fiu32::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) << " or " << U32().String(nullptr);
+ return ss.str();
}
/// TypeMatcher for 'match fi32'
-/// @see src/tint/intrinsics.def:112:7
+/// @see src/tint/intrinsics.def:128:7
class Fi32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
/// expected, canonicalized type on success.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -1205,30 +1564,34 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Fi32::Match(MatchState& state, const sem::Type* ty) const {
- if (match_f32(ty)) {
- return build_f32(state);
- }
if (match_i32(ty)) {
return build_i32(state);
}
+ if (match_f32(ty)) {
+ return build_f32(state);
+ }
return nullptr;
}
-std::string Fi32::String(MatchState&) const {
- return "f32 or i32";
+std::string Fi32::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 " << I32().String(nullptr);
+ return ss.str();
}
/// TypeMatcher for 'match iu32'
-/// @see src/tint/intrinsics.def:113:7
+/// @see src/tint/intrinsics.def:129:7
class Iu32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
/// expected, canonicalized type on success.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -1236,7 +1599,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Iu32::Match(MatchState& state, const sem::Type* ty) const {
@@ -1249,17 +1612,21 @@
return nullptr;
}
-std::string Iu32::String(MatchState&) const {
- return "i32 or u32";
+std::string Iu32::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 << I32().String(nullptr) << " or " << U32().String(nullptr);
+ return ss.str();
}
/// TypeMatcher for 'match scalar'
-/// @see src/tint/intrinsics.def:114:7
+/// @see src/tint/intrinsics.def:130:7
class Scalar : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
/// expected, canonicalized type on success.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -1267,13 +1634,133 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* Scalar::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 Scalar::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 abstract_or_scalar'
+/// @see src/tint/intrinsics.def:131:7
+class AbstractOrScalar : 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* AbstractOrScalar::Match(MatchState& state, const sem::Type* ty) const {
+ if (match_af(ty)) {
+ return build_af(state);
+ }
+ if (match_ai(ty)) {
+ return build_ai(state);
+ }
+ 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 AbstractOrScalar::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 << Ai().String(nullptr) << ", " << Af().String(nullptr) << ", " << F32().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:132:7
+class AfF32 : 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* AfF32::Match(MatchState& state, const sem::Type* ty) const {
+ if (match_af(ty)) {
+ return build_af(state);
+ }
+ if (match_f32(ty)) {
+ return build_f32(state);
+ }
+ return nullptr;
+}
+
+std::string AfF32::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) << " or " << F32().String(nullptr);
+ return ss.str();
+}
+
+/// TypeMatcher for 'match scalar_no_f32'
+/// @see src/tint/intrinsics.def:133:7
+class ScalarNoF32 : 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* ScalarNoF32::Match(MatchState& state, const sem::Type* ty) const {
if (match_i32(ty)) {
return build_i32(state);
}
@@ -1286,23 +1773,141 @@
return nullptr;
}
-std::string Scalar::String(MatchState&) const {
- return "f32, i32, u32 or bool";
+std::string ScalarNoF32::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 << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
+ return ss.str();
+}
+
+/// TypeMatcher for 'match scalar_no_i32'
+/// @see src/tint/intrinsics.def:134:7
+class ScalarNoI32 : 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* ScalarNoI32::Match(MatchState& state, const sem::Type* ty) const {
+ 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 ScalarNoI32::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) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
+ return ss.str();
+}
+
+/// TypeMatcher for 'match scalar_no_u32'
+/// @see src/tint/intrinsics.def:135:7
+class ScalarNoU32 : 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* ScalarNoU32::Match(MatchState& state, const sem::Type* ty) const {
+ if (match_i32(ty)) {
+ return build_i32(state);
+ }
+ if (match_f32(ty)) {
+ return build_f32(state);
+ }
+ if (match_bool(ty)) {
+ return build_bool(state);
+ }
+ return nullptr;
+}
+
+std::string ScalarNoU32::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) << " or " << Bool().String(nullptr);
+ return ss.str();
+}
+
+/// TypeMatcher for 'match scalar_no_bool'
+/// @see src/tint/intrinsics.def:136:7
+class ScalarNoBool : 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* ScalarNoBool::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);
+ }
+ return nullptr;
+}
+
+std::string ScalarNoBool::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) << " or " << U32().String(nullptr);
+ return ss.str();
}
/// EnumMatcher for 'match f32_texel_format'
-/// @see src/tint/intrinsics.def:125:7
+/// @see src/tint/intrinsics.def:147:7
class F32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
- /// Match may close open types and numbers in state.
+ /// Match may define template numbers in state.
/// @param state the MatchState
/// @param number the enum value as a Number
/// @return true if the enum value matches the set
Number Match(MatchState& state, Number number) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
Number F32TexelFormat::Match(MatchState&, Number number) const {
@@ -1319,23 +1924,23 @@
}
}
-std::string F32TexelFormat::String(MatchState&) const {
+std::string F32TexelFormat::String(MatchState*) const {
return "rgba8unorm, rgba8snorm, rgba16float, r32float, rg32float or rgba32float";
}
/// EnumMatcher for 'match i32_texel_format'
-/// @see src/tint/intrinsics.def:127:7
+/// @see src/tint/intrinsics.def:149:7
class I32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
- /// Match may close open types and numbers in state.
+ /// Match may define template numbers in state.
/// @param state the MatchState
/// @param number the enum value as a Number
/// @return true if the enum value matches the set
Number Match(MatchState& state, Number number) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
Number I32TexelFormat::Match(MatchState&, Number number) const {
@@ -1351,23 +1956,23 @@
}
}
-std::string I32TexelFormat::String(MatchState&) const {
+std::string I32TexelFormat::String(MatchState*) const {
return "rgba8sint, rgba16sint, r32sint, rg32sint or rgba32sint";
}
/// EnumMatcher for 'match u32_texel_format'
-/// @see src/tint/intrinsics.def:129:7
+/// @see src/tint/intrinsics.def:151:7
class U32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
- /// Match may close open types and numbers in state.
+ /// Match may define template numbers in state.
/// @param state the MatchState
/// @param number the enum value as a Number
/// @return true if the enum value matches the set
Number Match(MatchState& state, Number number) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
Number U32TexelFormat::Match(MatchState&, Number number) const {
@@ -1383,23 +1988,23 @@
}
}
-std::string U32TexelFormat::String(MatchState&) const {
+std::string U32TexelFormat::String(MatchState*) const {
return "rgba8uint, rgba16uint, r32uint, rg32uint or rgba32uint";
}
/// EnumMatcher for 'match write_only'
-/// @see src/tint/intrinsics.def:132:7
+/// @see src/tint/intrinsics.def:154:7
class WriteOnly : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
- /// Match may close open types and numbers in state.
+ /// Match may define template numbers in state.
/// @param state the MatchState
/// @param number the enum value as a Number
/// @return true if the enum value matches the set
Number Match(MatchState& state, Number number) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
Number WriteOnly::Match(MatchState&, Number number) const {
@@ -1409,23 +2014,23 @@
return Number::invalid;
}
-std::string WriteOnly::String(MatchState&) const {
+std::string WriteOnly::String(MatchState*) const {
return "write";
}
/// EnumMatcher for 'match function_private_workgroup'
-/// @see src/tint/intrinsics.def:134:7
+/// @see src/tint/intrinsics.def:156:7
class FunctionPrivateWorkgroup : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
- /// Match may close open types and numbers in state.
+ /// Match may define template numbers in state.
/// @param state the MatchState
/// @param number the enum value as a Number
/// @return true if the enum value matches the set
Number Match(MatchState& state, Number number) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
Number FunctionPrivateWorkgroup::Match(MatchState&, Number number) const {
@@ -1439,23 +2044,23 @@
}
}
-std::string FunctionPrivateWorkgroup::String(MatchState&) const {
+std::string FunctionPrivateWorkgroup::String(MatchState*) const {
return "function, private or workgroup";
}
/// EnumMatcher for 'match workgroup_or_storage'
-/// @see src/tint/intrinsics.def:135:7
+/// @see src/tint/intrinsics.def:157:7
class WorkgroupOrStorage : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
- /// Match may close open types and numbers in state.
+ /// Match may define template numbers in state.
/// @param state the MatchState
/// @param number the enum value as a Number
/// @return true if the enum value matches the set
Number Match(MatchState& state, Number number) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
Number WorkgroupOrStorage::Match(MatchState&, Number number) const {
@@ -1468,7 +2073,7 @@
}
}
-std::string WorkgroupOrStorage::String(MatchState&) const {
+std::string WorkgroupOrStorage::String(MatchState*) const {
return "workgroup or storage";
}
@@ -1476,14 +2081,14 @@
class Storage : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
- /// Match may close open types and numbers in state.
+ /// Match may define template numbers in state.
/// @param state the MatchState
/// @param number the enum value as a Number
/// @return true if the enum value matches the set
Number Match(MatchState& state, Number number) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
Number Storage::Match(MatchState&, Number number) const {
@@ -1493,7 +2098,7 @@
return Number::invalid;
}
-std::string Storage::String(MatchState&) const {
+std::string Storage::String(MatchState*) const {
return "storage";
}
@@ -1501,14 +2106,14 @@
class Write : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
- /// Match may close open types and numbers in state.
+ /// Match may define template numbers in state.
/// @param state the MatchState
/// @param number the enum value as a Number
/// @return true if the enum value matches the set
Number Match(MatchState& state, Number number) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
Number Write::Match(MatchState&, Number number) const {
@@ -1518,7 +2123,7 @@
return Number::invalid;
}
-std::string Write::String(MatchState&) const {
+std::string Write::String(MatchState*) const {
return "write";
}
@@ -1526,14 +2131,14 @@
class ReadWrite : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
- /// Match may close open types and numbers in state.
+ /// Match may define template numbers in state.
/// @param state the MatchState
/// @param number the enum value as a Number
/// @return true if the enum value matches the set
Number Match(MatchState& state, Number number) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
Number ReadWrite::Match(MatchState&, Number number) const {
@@ -1543,24 +2148,36 @@
return Number::invalid;
}
-std::string ReadWrite::String(MatchState&) const {
+std::string ReadWrite::String(MatchState*) const {
return "read_write";
}
/// Matchers holds type and number matchers
class Matchers {
private:
- OpenTypeMatcher open_type_0_{0};
- OpenNumberMatcher open_number_0_{0};
- OpenNumberMatcher open_number_1_{1};
- OpenNumberMatcher open_number_2_{2};
+ TemplateTypeMatcher template_type_0_{0};
+ TemplateTypeMatcher template_type_1_{1};
+ TemplateNumberMatcher template_number_0_{0};
+ TemplateNumberMatcher template_number_1_{1};
+ TemplateNumberMatcher template_number_2_{2};
Bool Bool_;
- F32 F32_;
+ Af Af_;
+ Ai Ai_;
I32 I32_;
U32 U32_;
+ F32 F32_;
Vec2 Vec2_;
Vec3 Vec3_;
Vec4 Vec4_;
+ Mat2X2 Mat2X2_;
+ Mat2X3 Mat2X3_;
+ Mat2X4 Mat2X4_;
+ Mat3X2 Mat3X2_;
+ Mat3X3 Mat3X3_;
+ Mat3X4 Mat3X4_;
+ Mat4X2 Mat4X2_;
+ Mat4X3 Mat4X3_;
+ Mat4X4 Mat4X4_;
Vec Vec_;
Mat Mat_;
Ptr Ptr_;
@@ -1593,6 +2210,12 @@
Fi32 Fi32_;
Iu32 Iu32_;
Scalar Scalar_;
+ AbstractOrScalar AbstractOrScalar_;
+ AfF32 AfF32_;
+ ScalarNoF32 ScalarNoF32_;
+ ScalarNoI32 ScalarNoI32_;
+ ScalarNoU32 ScalarNoU32_;
+ ScalarNoBool ScalarNoBool_;
F32TexelFormat F32TexelFormat_;
I32TexelFormat I32TexelFormat_;
U32TexelFormat U32TexelFormat_;
@@ -1609,55 +2232,73 @@
/// Destructor
~Matchers();
- /// The open-types, types, and type matchers
- TypeMatcher const* const type[40] = {
- /* [0] */ &open_type_0_,
- /* [1] */ &Bool_,
- /* [2] */ &F32_,
- /* [3] */ &I32_,
- /* [4] */ &U32_,
- /* [5] */ &Vec2_,
- /* [6] */ &Vec3_,
- /* [7] */ &Vec4_,
- /* [8] */ &Vec_,
- /* [9] */ &Mat_,
- /* [10] */ &Ptr_,
- /* [11] */ &Atomic_,
- /* [12] */ &Array_,
- /* [13] */ &Sampler_,
- /* [14] */ &SamplerComparison_,
- /* [15] */ &Texture1D_,
- /* [16] */ &Texture2D_,
- /* [17] */ &Texture2DArray_,
- /* [18] */ &Texture3D_,
- /* [19] */ &TextureCube_,
- /* [20] */ &TextureCubeArray_,
- /* [21] */ &TextureMultisampled2D_,
- /* [22] */ &TextureDepth2D_,
- /* [23] */ &TextureDepth2DArray_,
- /* [24] */ &TextureDepthCube_,
- /* [25] */ &TextureDepthCubeArray_,
- /* [26] */ &TextureDepthMultisampled2D_,
- /* [27] */ &TextureStorage1D_,
- /* [28] */ &TextureStorage2D_,
- /* [29] */ &TextureStorage2DArray_,
- /* [30] */ &TextureStorage3D_,
- /* [31] */ &TextureExternal_,
- /* [32] */ &ModfResult_,
- /* [33] */ &ModfResultVec_,
- /* [34] */ &FrexpResult_,
- /* [35] */ &FrexpResultVec_,
- /* [36] */ &Fiu32_,
- /* [37] */ &Fi32_,
- /* [38] */ &Iu32_,
- /* [39] */ &Scalar_,
+ /// The template types, types, and type matchers
+ TypeMatcher const* const type[58] = {
+ /* [0] */ &template_type_0_,
+ /* [1] */ &template_type_1_,
+ /* [2] */ &Bool_,
+ /* [3] */ &Af_,
+ /* [4] */ &Ai_,
+ /* [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] */ &Fiu32_,
+ /* [49] */ &Fi32_,
+ /* [50] */ &Iu32_,
+ /* [51] */ &Scalar_,
+ /* [52] */ &AbstractOrScalar_,
+ /* [53] */ &AfF32_,
+ /* [54] */ &ScalarNoF32_,
+ /* [55] */ &ScalarNoI32_,
+ /* [56] */ &ScalarNoU32_,
+ /* [57] */ &ScalarNoBool_,
};
- /// The open-numbers, and number matchers
+ /// The template numbers, and number matchers
NumberMatcher const* const number[12] = {
- /* [0] */ &open_number_0_,
- /* [1] */ &open_number_1_,
- /* [2] */ &open_number_2_,
+ /* [0] */ &template_number_0_,
+ /* [1] */ &template_number_1_,
+ /* [2] */ &template_number_2_,
/* [3] */ &F32TexelFormat_,
/* [4] */ &I32TexelFormat_,
/* [5] */ &U32TexelFormat_,
@@ -1674,159 +2315,207 @@
Matchers::~Matchers() = default;
constexpr MatcherIndex kMatcherIndices[] = {
- /* [0] */ 30,
- /* [1] */ 4,
- /* [2] */ 10,
+ /* [0] */ 22,
+ /* [1] */ 0,
+ /* [2] */ 23,
/* [3] */ 0,
/* [4] */ 11,
- /* [5] */ 0,
- /* [6] */ 11,
- /* [7] */ 10,
- /* [8] */ 9,
- /* [9] */ 12,
+ /* [5] */ 7,
+ /* [6] */ 22,
+ /* [7] */ 9,
+ /* [8] */ 24,
+ /* [9] */ 0,
/* [10] */ 0,
- /* [11] */ 0,
- /* [12] */ 9,
- /* [13] */ 0,
- /* [14] */ 0,
- /* [15] */ 2,
- /* [16] */ 9,
+ /* [11] */ 21,
+ /* [12] */ 0,
+ /* [13] */ 1,
+ /* [14] */ 7,
+ /* [15] */ 21,
+ /* [16] */ 0,
/* [17] */ 0,
- /* [18] */ 1,
- /* [19] */ 2,
- /* [20] */ 9,
- /* [21] */ 1,
- /* [22] */ 0,
- /* [23] */ 2,
- /* [24] */ 9,
+ /* [18] */ 7,
+ /* [19] */ 21,
+ /* [20] */ 0,
+ /* [21] */ 2,
+ /* [22] */ 7,
+ /* [23] */ 21,
+ /* [24] */ 1,
/* [25] */ 0,
- /* [26] */ 2,
- /* [27] */ 2,
- /* [28] */ 9,
- /* [29] */ 1,
- /* [30] */ 2,
- /* [31] */ 2,
- /* [32] */ 8,
- /* [33] */ 0,
- /* [34] */ 2,
- /* [35] */ 8,
- /* [36] */ 0,
- /* [37] */ 1,
- /* [38] */ 8,
+ /* [26] */ 7,
+ /* [27] */ 21,
+ /* [28] */ 1,
+ /* [29] */ 2,
+ /* [30] */ 7,
+ /* [31] */ 20,
+ /* [32] */ 0,
+ /* [33] */ 7,
+ /* [34] */ 41,
+ /* [35] */ 0,
+ /* [36] */ 1,
+ /* [37] */ 20,
+ /* [38] */ 0,
/* [39] */ 0,
- /* [40] */ 0,
- /* [41] */ 29,
- /* [42] */ 0,
- /* [43] */ 1,
- /* [44] */ 30,
- /* [45] */ 0,
- /* [46] */ 1,
- /* [47] */ 8,
- /* [48] */ 1,
- /* [49] */ 2,
- /* [50] */ 28,
- /* [51] */ 0,
- /* [52] */ 1,
- /* [53] */ 27,
- /* [54] */ 0,
- /* [55] */ 1,
- /* [56] */ 8,
- /* [57] */ 0,
- /* [58] */ 3,
- /* [59] */ 8,
- /* [60] */ 0,
- /* [61] */ 4,
- /* [62] */ 27,
- /* [63] */ 3,
- /* [64] */ 10,
- /* [65] */ 28,
- /* [66] */ 3,
- /* [67] */ 10,
- /* [68] */ 29,
- /* [69] */ 3,
- /* [70] */ 10,
- /* [71] */ 30,
- /* [72] */ 3,
- /* [73] */ 10,
- /* [74] */ 27,
- /* [75] */ 4,
- /* [76] */ 10,
- /* [77] */ 28,
- /* [78] */ 4,
- /* [79] */ 10,
- /* [80] */ 30,
- /* [81] */ 5,
- /* [82] */ 10,
- /* [83] */ 29,
- /* [84] */ 5,
- /* [85] */ 10,
- /* [86] */ 29,
- /* [87] */ 4,
- /* [88] */ 10,
- /* [89] */ 28,
- /* [90] */ 5,
- /* [91] */ 10,
- /* [92] */ 27,
- /* [93] */ 5,
- /* [94] */ 10,
- /* [95] */ 6,
- /* [96] */ 3,
- /* [97] */ 7,
- /* [98] */ 3,
+ /* [40] */ 20,
+ /* [41] */ 0,
+ /* [42] */ 2,
+ /* [43] */ 42,
+ /* [44] */ 5,
+ /* [45] */ 10,
+ /* [46] */ 7,
+ /* [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,
+ /* [64] */ 4,
+ /* [65] */ 10,
+ /* [66] */ 2,
+ /* [67] */ 40,
+ /* [68] */ 4,
+ /* [69] */ 10,
+ /* [70] */ 39,
+ /* [71] */ 4,
+ /* [72] */ 10,
+ /* [73] */ 42,
+ /* [74] */ 3,
+ /* [75] */ 10,
+ /* [76] */ 20,
+ /* [77] */ 1,
+ /* [78] */ 7,
+ /* [79] */ 42,
+ /* [80] */ 0,
+ /* [81] */ 1,
+ /* [82] */ 40,
+ /* [83] */ 0,
+ /* [84] */ 1,
+ /* [85] */ 39,
+ /* [86] */ 0,
+ /* [87] */ 1,
+ /* [88] */ 41,
+ /* [89] */ 3,
+ /* [90] */ 10,
+ /* [91] */ 40,
+ /* [92] */ 3,
+ /* [93] */ 10,
+ /* [94] */ 39,
+ /* [95] */ 3,
+ /* [96] */ 10,
+ /* [97] */ 20,
+ /* [98] */ 0,
/* [99] */ 5,
- /* [100] */ 3,
- /* [101] */ 7,
- /* [102] */ 4,
- /* [103] */ 15,
- /* [104] */ 0,
- /* [105] */ 7,
+ /* [100] */ 20,
+ /* [101] */ 0,
+ /* [102] */ 6,
+ /* [103] */ 8,
+ /* [104] */ 7,
+ /* [105] */ 8,
/* [106] */ 0,
- /* [107] */ 16,
- /* [108] */ 0,
- /* [109] */ 7,
- /* [110] */ 2,
- /* [111] */ 17,
- /* [112] */ 0,
- /* [113] */ 5,
+ /* [107] */ 8,
+ /* [108] */ 1,
+ /* [109] */ 8,
+ /* [110] */ 5,
+ /* [111] */ 8,
+ /* [112] */ 6,
+ /* [113] */ 8,
/* [114] */ 2,
- /* [115] */ 33,
+ /* [115] */ 9,
/* [116] */ 0,
- /* [117] */ 18,
+ /* [117] */ 45,
/* [118] */ 0,
- /* [119] */ 21,
- /* [120] */ 0,
- /* [121] */ 6,
- /* [122] */ 2,
- /* [123] */ 20,
- /* [124] */ 2,
- /* [125] */ 19,
- /* [126] */ 0,
- /* [127] */ 19,
+ /* [119] */ 9,
+ /* [120] */ 1,
+ /* [121] */ 9,
+ /* [122] */ 7,
+ /* [123] */ 9,
+ /* [124] */ 5,
+ /* [125] */ 9,
+ /* [126] */ 6,
+ /* [127] */ 9,
/* [128] */ 2,
- /* [129] */ 20,
+ /* [129] */ 27,
/* [130] */ 0,
- /* [131] */ 18,
- /* [132] */ 2,
- /* [133] */ 17,
- /* [134] */ 2,
- /* [135] */ 5,
+ /* [131] */ 28,
+ /* [132] */ 0,
+ /* [133] */ 29,
+ /* [134] */ 0,
+ /* [135] */ 47,
/* [136] */ 0,
- /* [137] */ 35,
+ /* [137] */ 19,
/* [138] */ 0,
- /* [139] */ 16,
- /* [140] */ 2,
- /* [141] */ 15,
- /* [142] */ 2,
- /* [143] */ 13,
- /* [144] */ 23,
- /* [145] */ 24,
- /* [146] */ 25,
- /* [147] */ 22,
- /* [148] */ 26,
- /* [149] */ 14,
- /* [150] */ 31,
- /* [151] */ 32,
- /* [152] */ 34,
+ /* [139] */ 30,
+ /* [140] */ 0,
+ /* [141] */ 31,
+ /* [142] */ 0,
+ /* [143] */ 32,
+ /* [144] */ 0,
+ /* [145] */ 33,
+ /* [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] */ 18,
+ /* [174] */ 7,
+ /* [175] */ 18,
+ /* [176] */ 0,
+ /* [177] */ 27,
+ /* [178] */ 7,
+ /* [179] */ 28,
+ /* [180] */ 7,
+ /* [181] */ 29,
+ /* [182] */ 7,
+ /* [183] */ 19,
+ /* [184] */ 7,
+ /* [185] */ 30,
+ /* [186] */ 7,
+ /* [187] */ 31,
+ /* [188] */ 7,
+ /* [189] */ 32,
+ /* [190] */ 7,
+ /* [191] */ 25,
+ /* [192] */ 26,
+ /* [193] */ 37,
+ /* [194] */ 36,
+ /* [195] */ 35,
+ /* [196] */ 34,
+ /* [197] */ 43,
+ /* [198] */ 38,
+ /* [199] */ 44,
+ /* [200] */ 46,
};
// Assert that the MatcherIndex is big enough to index all the matchers, plus
@@ -1838,1363 +2527,1363 @@
constexpr ParameterInfo kParameters[] = {
{
/* [0] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [1] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [2] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [3] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [4] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [5] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [6] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [7] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [8] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [9] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [10] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [11] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [12] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [13] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [14] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [15] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [16] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [17] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [18] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [19] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [20] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [21] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [22] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [23] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [24] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [25] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [26] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [27] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [28] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [29] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [30] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [31] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [32] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [33] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [34] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [35] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [36] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [37] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [38] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [39] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [40] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [41] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [42] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [43] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [44] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [45] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [46] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [47] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [48] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[95],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [49] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [50] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [51] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [52] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [53] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [54] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [55] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [56] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [57] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [58] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [59] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [60] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [61] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [62] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [63] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [64] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [65] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[181],
},
{
/* [66] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [67] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [68] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [69] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [70] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [71] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [72] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
},
{
/* [73] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [74] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [75] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [76] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [77] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[95],
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [78] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [79] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [80] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [81] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [82] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [83] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [84] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[179],
},
{
/* [85] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [86] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [87] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [88] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [89] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [90] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [91] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [92] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [93] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [94] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [95] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [96] */
- /* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [97] */
- /* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[133],
},
{
/* [98] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [99] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [100] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [101] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [102] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[181],
},
{
/* [103] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [104] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [105] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [106] */
/* usage */ ParameterUsage::kDdx,
- /* matcher indices */ &kMatcherIndices[113],
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [107] */
/* usage */ ParameterUsage::kDdy,
- /* matcher indices */ &kMatcherIndices[113],
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [108] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[123],
+ /* matcher indices */ &kMatcherIndices[195],
},
{
/* [109] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [110] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [111] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [112] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [113] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [114] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[185],
},
{
/* [115] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [116] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [117] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [118] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
- },
- {
- /* [119] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
- },
- {
- /* [120] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
- },
- {
- /* [121] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [122] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [123] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[123],
- },
- {
- /* [124] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [125] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
- },
- {
- /* [126] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [127] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [128] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
- },
- {
- /* [129] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [130] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
- },
- {
- /* [131] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [132] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [133] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
- },
- {
- /* [134] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
- },
- {
- /* [135] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
- },
- {
- /* [136] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [137] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [138] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
- },
- {
- /* [139] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
- },
- {
- /* [140] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
- },
- {
- /* [141] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [142] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [143] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[127],
- },
- {
- /* [144] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [145] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
- },
- {
- /* [146] */
/* usage */ ParameterUsage::kDdx,
/* matcher indices */ &kMatcherIndices[121],
},
{
- /* [147] */
+ /* [118] */
/* usage */ ParameterUsage::kDdy,
/* matcher indices */ &kMatcherIndices[121],
},
{
- /* [148] */
+ /* [119] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[123],
+ },
+ {
+ /* [120] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
+ /* matcher indices */ &kMatcherIndices[189],
+ },
+ {
+ /* [121] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [122] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
+ },
+ {
+ /* [123] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [124] */
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[121],
+ },
+ {
+ /* [125] */
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[121],
+ },
+ {
+ /* [126] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[181],
+ },
+ {
+ /* [127] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [128] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [129] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [130] */
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [131] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
+ },
+ {
+ /* [132] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[181],
+ },
+ {
+ /* [133] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [134] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [135] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [136] */
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [137] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
+ },
+ {
+ /* [138] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
+ },
+ {
+ /* [139] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
+ },
+ {
+ /* [140] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [141] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [142] */
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [143] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
+ },
+ {
+ /* [144] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
+ },
+ {
+ /* [145] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
+ },
+ {
+ /* [146] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [147] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [148] */
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [149] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [150] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
},
{
/* [151] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [152] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [153] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [154] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [155] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [156] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [157] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [158] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [159] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [160] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[193],
},
{
/* [161] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [162] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [163] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [164] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [165] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[189],
},
{
/* [166] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [167] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [168] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [169] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [170] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[193],
},
{
/* [171] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [172] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [173] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [174] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [175] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[185],
},
{
/* [176] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [177] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [178] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [179] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[123],
},
{
/* [180] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[179],
},
{
/* [181] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [182] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [183] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [184] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [185] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
},
{
/* [186] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [187] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [188] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [189] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [190] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[181],
},
{
/* [191] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [192] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [193] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[133],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [194] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [195] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[179],
},
{
/* [196] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [197] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [198] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [199] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[129],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [200] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
},
{
/* [201] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [202] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [203] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [204] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[107],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [205] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [206] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [207] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [208] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [209] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [210] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[187],
},
{
/* [211] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [212] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [213] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [214] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [215] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[181],
},
{
/* [216] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [217] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[95],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [218] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [219] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[125],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [220] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[185],
},
{
/* [221] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [222] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[121],
},
{
- /* [222] */
- /* usage */ ParameterUsage::kComponent,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
/* [223] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[107],
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [224] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [225] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
},
{
/* [226] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [227] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [228] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [229] */
/* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [230] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [231] */
- /* usage */ ParameterUsage::kSampler,
+ /* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[143],
},
{
/* [232] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [233] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [234] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [235] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [236] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[133],
},
{
/* [237] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [238] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[145],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [239] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [240] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[179],
+ },
+ {
+ /* [241] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [242] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [243] */
+ /* usage */ ParameterUsage::kDdx,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [244] */
+ /* usage */ ParameterUsage::kDdy,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [245] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[193],
+ },
+ {
+ /* [246] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
+ },
+ {
+ /* [247] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[121],
},
{
- /* [241] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [242] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
- },
- {
- /* [243] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
- },
- {
- /* [244] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
- },
- {
- /* [245] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [246] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
- },
- {
- /* [247] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
- },
- {
/* [248] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [249] */
/* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [250] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[68],
+ /* matcher indices */ &kMatcherIndices[185],
},
{
/* [251] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [252] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [253] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [254] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[145],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[123],
},
{
/* [255] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [256] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
- },
- {
- /* [257] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [258] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
- },
- {
- /* [259] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
- },
- {
- /* [260] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
- },
- {
- /* [261] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [262] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[145],
- },
- {
- /* [263] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[149],
- },
- {
- /* [264] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
- },
- {
- /* [265] */
- /* usage */ ParameterUsage::kDepthRef,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [266] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[127],
- },
- {
- /* [267] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [268] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
- },
- {
- /* [269] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [270] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[131],
},
{
+ /* [257] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [258] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [259] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
+ },
+ {
+ /* [260] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
+ },
+ {
+ /* [261] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
+ },
+ {
+ /* [262] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [263] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [264] */
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [265] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
+ },
+ {
+ /* [266] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
+ },
+ {
+ /* [267] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [268] */
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [269] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
+ },
+ {
+ /* [270] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[189],
+ },
+ {
/* [271] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [272] */
@@ -3203,1928 +3892,1928 @@
},
{
/* [273] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [274] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [275] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[193],
},
{
/* [276] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [277] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [278] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[127],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [279] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [280] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [281] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [282] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[145],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [283] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [284] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [285] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
},
{
/* [286] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [287] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [288] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [289] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [290] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
+ /* matcher indices */ &kMatcherIndices[181],
},
{
/* [291] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [292] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [293] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [294] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [295] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [296] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [297] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [298] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [299] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [300] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [301] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [302] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [303] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [304] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [305] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [306] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[83],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [307] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[187],
},
{
/* [308] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [309] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[101],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [310] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [311] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [312] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [313] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [314] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[123],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [315] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[185],
},
{
/* [316] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [317] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [318] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
- },
- {
- /* [319] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [320] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[121],
},
{
+ /* [318] */
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [319] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[179],
+ },
+ {
+ /* [320] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
/* [321] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[95],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [322] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[86],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [323] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
- },
- {
- /* [324] */
- /* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [325] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[97],
- },
- {
- /* [326] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
- },
- {
- /* [327] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [328] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
- },
- {
- /* [329] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[15],
- },
- {
- /* [330] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
- },
- {
- /* [331] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [332] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
- },
- {
- /* [333] */
- /* usage */ ParameterUsage::kOffset,
- /* matcher indices */ &kMatcherIndices[99],
- },
- {
- /* [334] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[133],
},
{
- /* [335] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [336] */
+ /* [324] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* matcher indices */ &kMatcherIndices[109],
},
{
- /* [337] */
+ /* [325] */
/* usage */ ParameterUsage::kArrayIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* matcher indices */ &kMatcherIndices[44],
},
{
- /* [338] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* [326] */
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
- /* [339] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
- },
- {
- /* [340] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [341] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
- },
- {
- /* [342] */
+ /* [327] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
+ /* matcher indices */ &kMatcherIndices[185],
},
{
- /* [343] */
+ /* [328] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* matcher indices */ &kMatcherIndices[191],
},
{
- /* [344] */
+ /* [329] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[121],
},
{
- /* [345] */
+ /* [330] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [331] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[179],
+ },
+ {
+ /* [332] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [333] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [334] */
+ /* usage */ ParameterUsage::kBias,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [335] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[193],
+ },
+ {
+ /* [336] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [337] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
+ },
+ {
+ /* [338] */
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [339] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[187],
+ },
+ {
+ /* [340] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [341] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
+ },
+ {
+ /* [342] */
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [343] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
+ },
+ {
+ /* [344] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [345] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [346] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [347] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [348] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [349] */
- /* usage */ ParameterUsage::kBias,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [350] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[74],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [351] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[189],
},
{
/* [352] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[97],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [353] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [354] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [355] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[185],
},
{
/* [356] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [357] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [358] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[123],
},
{
/* [359] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [360] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[131],
},
{
/* [361] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [362] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [363] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[181],
},
{
/* [364] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [365] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [366] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [367] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[179],
},
{
/* [368] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [369] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [370] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [371] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [372] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [373] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [374] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[145],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [375] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [376] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [377] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[131],
- },
- {
- /* [378] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [379] */
/* usage */ ParameterUsage::kCoords,
/* matcher indices */ &kMatcherIndices[121],
},
{
+ /* [378] */
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [379] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[194],
+ },
+ {
/* [380] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [381] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [382] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [383] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[88],
},
{
/* [384] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [385] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [386] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [387] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[63],
},
{
/* [388] */
- /* usage */ ParameterUsage::kSampleIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [389] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [390] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[57],
},
{
/* [391] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [392] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [393] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [394] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kDepthRef,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [395] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[193],
},
{
/* [396] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [397] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [398] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [399] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[47],
},
{
/* [400] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [401] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [402] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[61],
},
{
/* [403] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [404] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [405] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [406] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [407] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
},
{
/* [408] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [409] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [410] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [411] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
},
{
/* [412] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [413] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[119],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [414] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kArrayIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [415] */
- /* usage */ ParameterUsage::kSampleIndex,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [416] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [417] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[95],
- },
- {
- /* [418] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [419] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[145],
- },
- {
- /* [420] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [421] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
- },
- {
- /* [422] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[107],
- },
- {
- /* [423] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
- },
- {
- /* [424] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [425] */
- /* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[103],
},
{
- /* [426] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[58],
+ /* [418] */
+ /* usage */ ParameterUsage::kOffset,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
- /* [427] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* [419] */
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
- /* [428] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[80],
+ /* [420] */
+ /* usage */ ParameterUsage::kY,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
- /* [429] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[95],
+ /* [421] */
+ /* usage */ ParameterUsage::kZ,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
- /* [430] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[101],
+ /* [422] */
+ /* usage */ ParameterUsage::kW,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
- /* [431] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* [423] */
+ /* usage */ ParameterUsage::kComponent,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
- /* [432] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [433] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
- },
- {
- /* [434] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[127],
- },
- {
- /* [435] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [436] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[121],
- },
- {
- /* [437] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[150],
- },
- {
- /* [438] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
- },
- {
- /* [439] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
- },
- {
- /* [440] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[89],
- },
- {
- /* [441] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
- },
- {
- /* [442] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[101],
- },
- {
- /* [443] */
+ /* [424] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[141],
},
{
- /* [444] */
+ /* [425] */
/* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* matcher indices */ &kMatcherIndices[191],
},
{
- /* [445] */
+ /* [426] */
/* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[121],
},
{
- /* [446] */
- /* usage */ ParameterUsage::kTexture,
+ /* [427] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [428] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [429] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [430] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [431] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[105],
+ },
+ {
+ /* [432] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[105],
+ },
+ {
+ /* [433] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[105],
+ },
+ {
+ /* [434] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[105],
+ },
+ {
+ /* [435] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[115],
+ },
+ {
+ /* [436] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[115],
+ },
+ {
+ /* [437] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[115],
+ },
+ {
+ /* [438] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[115],
+ },
+ {
+ /* [439] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [440] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [441] */
+ /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[62],
},
{
+ /* [442] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[62],
+ },
+ {
+ /* [443] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[49],
+ },
+ {
+ /* [444] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[49],
+ },
+ {
+ /* [445] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[49],
+ },
+ {
+ /* [446] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[49],
+ },
+ {
/* [447] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [448] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [449] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [450] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [451] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [452] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[0],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [453] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[95],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [454] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[97],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [455] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[139],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [456] */
- /* usage */ ParameterUsage::kSampler,
- /* matcher indices */ &kMatcherIndices[143],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[197],
},
{
/* [457] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[113],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [458] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[77],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [459] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [460] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[97],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [461] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[65],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [462] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [463] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [464] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [465] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [466] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [467] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [468] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[49],
},
{
/* [469] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[49],
},
{
/* [470] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[49],
},
{
/* [471] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[115],
},
{
/* [472] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* matcher indices */ &kMatcherIndices[115],
},
{
/* [473] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[71],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[115],
},
{
/* [474] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[95],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [475] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[109],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [476] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[92],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [477] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[94],
},
{
/* [478] */
- /* usage */ ParameterUsage::kValue,
- /* matcher indices */ &kMatcherIndices[101],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [479] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [480] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[59],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[91],
},
{
/* [481] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [482] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [483] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[73],
},
{
/* [484] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[123],
},
{
/* [485] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[45],
},
{
/* [486] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[70],
},
{
/* [487] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [488] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[57],
},
{
/* [489] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[67],
},
{
/* [490] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [491] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[57],
},
{
/* [492] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[59],
},
{
/* [493] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[150],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[123],
},
{
/* [494] */
- /* usage */ ParameterUsage::kCoords,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[57],
},
{
/* [495] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [496] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [497] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [498] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [499] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [500] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [501] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [502] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kY,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [503] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* usage */ ParameterUsage::kZw,
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [504] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [505] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [506] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [507] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [508] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[58],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [509] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [510] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[56],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [511] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* usage */ ParameterUsage::kYz,
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [512] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kW,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [513] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* usage */ ParameterUsage::kXy,
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [514] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kZ,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [515] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* usage */ ParameterUsage::kW,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [516] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[55],
},
{
/* [517] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [518] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[61],
},
{
/* [519] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[51],
},
{
/* [520] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [521] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[61],
},
{
/* [522] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [523] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [524] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[21],
},
{
/* [525] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [526] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [527] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[21],
},
{
/* [528] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [529] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[16],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [530] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[16],
+ /* matcher indices */ &kMatcherIndices[40],
},
{
/* [531] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [532] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kY,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [533] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
+ /* usage */ ParameterUsage::kZ,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [534] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [535] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [536] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [537] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[107],
+ /* matcher indices */ &kMatcherIndices[43],
},
{
/* [538] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[123],
},
{
/* [539] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kValue,
+ /* matcher indices */ &kMatcherIndices[61],
},
{
/* [540] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
- },
- {
- /* [541] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[111],
- },
- {
- /* [542] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [543] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
- },
- {
- /* [544] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
- },
- {
- /* [545] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[117],
- },
- {
- /* [546] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [547] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[16],
- },
- {
- /* [548] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[16],
- },
- {
- /* [549] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[125],
- },
- {
- /* [550] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
- },
- {
- /* [551] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
- },
- {
- /* [552] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
- },
- {
- /* [553] */
/* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[129],
},
{
- /* [554] */
+ /* [541] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [542] */
/* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [543] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[131],
+ },
+ {
+ /* [544] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
+ },
+ {
+ /* [545] */
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [546] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
+ },
+ {
+ /* [547] */
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
+ },
+ {
+ /* [548] */
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [549] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [550] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [551] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [552] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [553] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [554] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [555] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [556] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [557] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [558] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [559] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [560] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [561] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [562] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[16],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [563] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [564] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[187],
},
{
/* [565] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[16],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [566] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [567] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[145],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [568] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [569] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[16],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [570] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[185],
},
{
/* [571] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [572] */
- /* usage */ ParameterUsage::kLevel,
- /* matcher indices */ &kMatcherIndices[58],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [573] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[47],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[139],
},
{
/* [574] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[16],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[123],
},
{
/* [575] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[24],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [576] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[20],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[145],
},
{
/* [577] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [578] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kSampleIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [579] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [580] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [581] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [582] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[179],
},
{
/* [583] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [584] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[103],
},
{
/* [585] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[177],
},
{
/* [586] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [587] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [588] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [589] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [590] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kSampleIndex,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [591] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [592] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [593] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [594] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [595] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kSampler,
+ /* matcher indices */ &kMatcherIndices[191],
},
{
/* [596] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [597] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [598] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [599] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [600] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [601] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [602] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [603] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[21],
},
{
/* [604] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[21],
},
{
/* [605] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[21],
},
{
/* [606] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[21],
},
{
/* [607] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [608] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [609] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [610] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [611] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[129],
},
{
/* [612] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[121],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [613] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* matcher indices */ &kMatcherIndices[40],
},
{
/* [614] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* matcher indices */ &kMatcherIndices[40],
},
{
/* [615] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[131],
},
{
/* [616] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [617] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[21],
},
{
/* [618] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[21],
},
{
/* [619] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[133],
},
{
/* [620] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [621] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [622] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [623] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[139],
},
{
/* [624] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [625] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [626] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [627] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[141],
},
{
/* [628] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [629] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[40],
},
{
/* [630] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[40],
},
{
/* [631] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[143],
},
{
/* [632] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [633] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[21],
},
{
/* [634] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[21],
},
{
/* [635] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [636] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [637] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [638] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [639] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [640] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [641] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
},
{
/* [642] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [643] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [644] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [645] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [646] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [647] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [648] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [649] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[193],
},
{
/* [650] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kLevel,
+ /* matcher indices */ &kMatcherIndices[44],
},
{
/* [651] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [652] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [653] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [654] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [655] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [656] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [657] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [658] */
@@ -5134,17 +5823,17 @@
{
/* [659] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [660] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[59],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [661] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [662] */
@@ -5154,212 +5843,212 @@
{
/* [663] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[19],
},
{
/* [664] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[23],
},
{
/* [665] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[76],
},
{
/* [666] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [667] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [668] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[119],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [669] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [670] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[145],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [671] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [672] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [673] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[129],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [674] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[125],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [675] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [676] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [677] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[107],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [678] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[16],
- },
- {
- /* [679] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
- },
- {
- /* [680] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[41],
- },
- {
- /* [681] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
- },
- {
- /* [682] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
- },
- {
- /* [683] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[129],
- },
- {
- /* [684] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[111],
- },
- {
- /* [685] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[150],
- },
- {
- /* [686] */
- /* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[44],
},
{
+ /* [679] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [680] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [681] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [682] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [683] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [684] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [685] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [686] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
/* [687] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[41],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [688] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[50],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [689] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[53],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [690] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[148],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [691] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[146],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [692] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[145],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [693] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[144],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [694] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[147],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [695] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[119],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [696] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[129],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [697] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[125],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [698] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[117],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[11],
},
{
/* [699] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[111],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [700] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[107],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [701] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[103],
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [702] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [703] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [704] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [705] */
@@ -5379,544 +6068,1519 @@
{
/* [708] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [709] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [710] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [711] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [712] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [713] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [714] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [715] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [716] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [717] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [718] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [719] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [720] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [721] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [722] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [723] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [724] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [725] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [726] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [727] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[197],
},
{
/* [728] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kCoords,
+ /* matcher indices */ &kMatcherIndices[109],
},
{
/* [729] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [730] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[109],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [731] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[113],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [732] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[113],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [733] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[113],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [734] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [735] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [736] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [737] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [738] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [739] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [740] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[2],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [741] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [742] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [743] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [744] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [745] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [746] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [747] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [748] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [749] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [750] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [751] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [752] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [753] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [754] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[100],
},
{
/* [755] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [756] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [757] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [758] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[100],
},
{
/* [759] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [760] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kY,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [761] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [762] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [763] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kXy,
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [764] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kZ,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [765] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [766] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kYz,
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [767] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [768] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [769] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kXy,
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [770] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kZw,
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [771] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [772] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [773] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [774] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [775] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kXyz,
+ /* matcher indices */ &kMatcherIndices[115],
},
{
/* [776] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* usage */ ParameterUsage::kW,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [777] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kX,
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [778] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* usage */ ParameterUsage::kZyw,
+ /* matcher indices */ &kMatcherIndices[115],
},
{
/* [779] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [780] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[105],
},
{
/* [781] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[115],
},
{
/* [782] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[115],
},
{
/* [783] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[49],
},
{
/* [784] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[12],
+ /* matcher indices */ &kMatcherIndices[49],
},
{
/* [785] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [786] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [787] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [788] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [789] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [790] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [791] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [792] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[121],
},
{
/* [793] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [794] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [795] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [796] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [797] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [798] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[37],
},
{
/* [799] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [800] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[62],
},
{
/* [801] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [802] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[15],
+ /* matcher indices */ &kMatcherIndices[97],
},
{
/* [803] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[7],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [804] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [805] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [806] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [807] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[18],
+ /* matcher indices */ &kMatcherIndices[5],
},
{
/* [808] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[32],
+ /* matcher indices */ &kMatcherIndices[31],
},
{
/* [809] */
/* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[15],
},
+ {
+ /* [810] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [811] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [812] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [813] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [814] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [815] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [816] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [817] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [818] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [819] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [820] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [821] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [822] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [823] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [824] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [825] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [826] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [827] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [828] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [829] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [830] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [831] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [832] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [833] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [834] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [835] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [836] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [837] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [838] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [839] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [840] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[34],
+ },
+ {
+ /* [841] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [842] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [843] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [844] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[198],
+ },
+ {
+ /* [845] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[145],
+ },
+ {
+ /* [846] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[193],
+ },
+ {
+ /* [847] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[0],
+ },
+ {
+ /* [848] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[194],
+ },
+ {
+ /* [849] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
+ },
+ {
+ /* [850] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
+ },
+ {
+ /* [851] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[143],
+ },
+ {
+ /* [852] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[141],
+ },
+ {
+ /* [853] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[139],
+ },
+ {
+ /* [854] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[133],
+ },
+ {
+ /* [855] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[131],
+ },
+ {
+ /* [856] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[129],
+ },
+ {
+ /* [857] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[34],
+ },
+ {
+ /* [858] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[21],
+ },
+ {
+ /* [859] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[40],
+ },
+ {
+ /* [860] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [861] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [862] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [863] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [864] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[193],
+ },
+ {
+ /* [865] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
+ },
+ {
+ /* [866] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[143],
+ },
+ {
+ /* [867] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[133],
+ },
+ {
+ /* [868] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [869] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [870] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [871] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [872] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [873] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [874] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [875] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [876] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [877] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [878] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [879] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [880] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [881] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [882] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [883] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[197],
+ },
+ {
+ /* [884] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[79],
+ },
+ {
+ /* [885] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [886] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[82],
+ },
+ {
+ /* [887] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[85],
+ },
+ {
+ /* [888] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[198],
+ },
+ {
+ /* [889] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[193],
+ },
+ {
+ /* [890] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[194],
+ },
+ {
+ /* [891] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[195],
+ },
+ {
+ /* [892] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[196],
+ },
+ {
+ /* [893] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[145],
+ },
+ {
+ /* [894] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[143],
+ },
+ {
+ /* [895] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[141],
+ },
+ {
+ /* [896] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[139],
+ },
+ {
+ /* [897] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[133],
+ },
+ {
+ /* [898] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[131],
+ },
+ {
+ /* [899] */
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[129],
+ },
+ {
+ /* [900] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [901] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[62],
+ },
+ {
+ /* [902] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[62],
+ },
+ {
+ /* [903] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[62],
+ },
+ {
+ /* [904] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[62],
+ },
+ {
+ /* [905] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [906] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [907] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [908] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[11],
+ },
+ {
+ /* [909] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [910] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [911] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [912] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [913] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [914] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [915] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [916] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [917] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [918] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [919] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[183],
+ },
+ {
+ /* [920] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[44],
+ },
+ {
+ /* [921] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [922] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [923] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[62],
+ },
+ {
+ /* [924] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [925] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [926] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [927] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [928] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [929] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[21],
+ },
+ {
+ /* [930] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [931] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[173],
+ },
+ {
+ /* [932] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[105],
+ },
+ {
+ /* [933] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [934] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [935] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[107],
+ },
+ {
+ /* [936] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[107],
+ },
+ {
+ /* [937] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[107],
+ },
+ {
+ /* [938] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[107],
+ },
+ {
+ /* [939] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[21],
+ },
+ {
+ /* [940] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[115],
+ },
+ {
+ /* [941] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [942] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [943] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [944] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [945] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[119],
+ },
+ {
+ /* [946] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[119],
+ },
+ {
+ /* [947] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[119],
+ },
+ {
+ /* [948] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[119],
+ },
+ {
+ /* [949] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[40],
+ },
+ {
+ /* [950] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[49],
+ },
+ {
+ /* [951] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [952] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [953] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[37],
+ },
+ {
+ /* [954] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [955] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [956] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [957] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [958] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[45],
+ },
+ {
+ /* [959] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[53],
+ },
+ {
+ /* [960] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[53],
+ },
+ {
+ /* [961] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[53],
+ },
+ {
+ /* [962] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[53],
+ },
+ {
+ /* [963] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [964] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[4],
+ },
+ {
+ /* [965] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [966] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [967] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [968] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[169],
+ },
+ {
+ /* [969] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[149],
+ },
+ {
+ /* [970] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [971] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [972] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [973] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [974] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[153],
+ },
+ {
+ /* [975] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [976] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[5],
+ },
+ {
+ /* [977] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[103],
+ },
+ {
+ /* [978] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[21],
+ },
+ {
+ /* [979] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[157],
+ },
+ {
+ /* [980] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [981] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[6],
+ },
+ {
+ /* [982] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[31],
+ },
+ {
+ /* [983] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [984] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[161],
+ },
+ {
+ /* [985] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[1],
+ },
+ {
+ /* [986] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[40],
+ },
+ {
+ /* [987] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[62],
+ },
+ {
+ /* [988] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[165],
+ },
+ {
+ /* [989] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[45],
+ },
};
-constexpr OpenTypeInfo kOpenTypes[] = {
+constexpr TemplateTypeInfo kTemplateTypes[] = {
{
/* [0] */
/* name */ "T",
- /* matcher index */ 36,
+ /* matcher index */ 2,
},
{
/* [1] */
- /* name */ "T",
- /* matcher index */ 38,
+ /* name */ "U",
+ /* matcher index */ 57,
},
{
/* [2] */
/* name */ "T",
- /* matcher index */ kNoMatcher,
+ /* matcher index */ 7,
},
{
/* [3] */
- /* name */ "T",
- /* matcher index */ 39,
+ /* name */ "U",
+ /* matcher index */ 54,
},
{
/* [4] */
/* name */ "T",
- /* matcher index */ 37,
+ /* matcher index */ 5,
+ },
+ {
+ /* [5] */
+ /* name */ "U",
+ /* matcher index */ 55,
+ },
+ {
+ /* [6] */
+ /* name */ "T",
+ /* matcher index */ 6,
+ },
+ {
+ /* [7] */
+ /* name */ "U",
+ /* matcher index */ 56,
+ },
+ {
+ /* [8] */
+ /* name */ "T",
+ /* matcher index */ 48,
+ },
+ {
+ /* [9] */
+ /* name */ "f32",
+ /* matcher index */ kNoMatcher,
+ },
+ {
+ /* [10] */
+ /* name */ "T",
+ /* matcher index */ 53,
+ },
+ {
+ /* [11] */
+ /* name */ "T",
+ /* matcher index */ 50,
+ },
+ {
+ /* [12] */
+ /* name */ "T",
+ /* matcher index */ 52,
+ },
+ {
+ /* [13] */
+ /* name */ "T",
+ /* matcher index */ 51,
+ },
+ {
+ /* [14] */
+ /* name */ "T",
+ /* matcher index */ kNoMatcher,
+ },
+ {
+ /* [15] */
+ /* name */ "T",
+ /* matcher index */ 57,
+ },
+ {
+ /* [16] */
+ /* name */ "T",
+ /* matcher index */ 54,
+ },
+ {
+ /* [17] */
+ /* name */ "T",
+ /* matcher index */ 56,
+ },
+ {
+ /* [18] */
+ /* name */ "T",
+ /* matcher index */ 55,
+ },
+ {
+ /* [19] */
+ /* name */ "T",
+ /* matcher index */ 49,
},
};
-constexpr OpenNumberInfo kOpenNumbers[] = {
+constexpr TemplateNumberInfo kTemplateNumbers[] = {
{
/* [0] */
/* name */ "K",
@@ -5973,4274 +7637,4897 @@
{
/* [0] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[701],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[899],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [1] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[533],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[611],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [2] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[700],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[898],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [3] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[537],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[615],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [4] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[699],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[897],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [5] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[541],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[619],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [6] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[698],
- /* return matcher indices */ &kMatcherIndices[95],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[896],
+ /* return matcher indices */ &kMatcherIndices[123],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [7] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[545],
- /* return matcher indices */ &kMatcherIndices[95],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[623],
+ /* return matcher indices */ &kMatcherIndices[123],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [8] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[697],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[895],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [9] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[549],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[627],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [10] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[696],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[894],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [11] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[553],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[631],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [12] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[695],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[893],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [13] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[694],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[892],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [14] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[559],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[637],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [15] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[693],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[891],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [16] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[563],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[641],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [17] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[692],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[890],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [18] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[567],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[645],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [19] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[691],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[889],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [20] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[571],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[649],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [21] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[690],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[888],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [22] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[3],
- /* parameters */ &kParameters[689],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[3],
+ /* parameters */ &kParameters[887],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [23] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[3],
- /* parameters */ &kParameters[688],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[3],
+ /* parameters */ &kParameters[886],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [24] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[3],
- /* parameters */ &kParameters[687],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[3],
+ /* parameters */ &kParameters[840],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [25] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[3],
- /* parameters */ &kParameters[686],
- /* return matcher indices */ &kMatcherIndices[95],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[3],
+ /* parameters */ &kParameters[884],
+ /* return matcher indices */ &kMatcherIndices[123],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [26] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[685],
- /* return matcher indices */ &kMatcherIndices[99],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[883],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [27] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[326],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[585],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [28] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[183],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[582],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [29] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[193],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[367],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [30] */
- /* num parameters */ 6,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[19],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[363],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [31] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[342],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[215],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [32] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[213],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[570],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [33] */
/* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[278],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[355],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [34] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[108],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[564],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [35] */
/* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[274],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[351],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [36] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[168],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[546],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [37] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[173],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[347],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [38] */
- /* num parameters */ 6,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[31],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[343],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [39] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[282],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[200],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [40] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[128],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[534],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [41] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[437],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[335],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [42] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[443],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[319],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [43] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[455],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[195],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [44] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[330],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[190],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [45] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[334],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[126],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [46] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[148],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[327],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [47] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[377],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[175],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [48] */
/* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[318],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[339],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [49] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[434],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[165],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [50] */
/* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[314],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[371],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [51] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[431],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[155],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [52] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[302],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[150],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [53] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[298],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[72],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [54] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[78],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* 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),
},
{
/* [55] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[419],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[170],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [56] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[290],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[456],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [57] */
- /* num parameters */ 4,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[222],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [58] */
- /* num parameters */ 5,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[203],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[950],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [59] */
- /* num parameters */ 5,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[208],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[951],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [60] */
- /* num parameters */ 6,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[49],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[419],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [61] */
- /* num parameters */ 4,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[218],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[513],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [62] */
- /* num parameters */ 5,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[198],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[510],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [63] */
/* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[371],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[501],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [64] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[226],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[769],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [65] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[230],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[775],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [66] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[178],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[777],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [67] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[374],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[2],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[959],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [68] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[234],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[4],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[960],
+ /* return matcher indices */ &kMatcherIndices[57],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [69] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[446],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[6],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[961],
+ /* return matcher indices */ &kMatcherIndices[61],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [70] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[461],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[0],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[962],
+ /* return matcher indices */ &kMatcherIndices[65],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [71] */
/* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[250],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[359],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [72] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[473],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[255],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [73] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[350],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[235],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [74] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[458],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[96],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [75] */
/* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[322],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[423],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [76] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[452],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[230],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [77] */
/* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[476],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[447],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [78] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[440],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[415],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [79] */
/* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[306],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[411],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [80] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[428],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[225],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [81] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[679],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[594],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [82] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[677],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[395],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [83] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[676],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[477],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [84] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[675],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[480],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [85] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[674],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[383],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [86] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[673],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[483],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [87] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[672],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[486],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [88] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[671],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[489],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [89] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[670],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[387],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [90] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[669],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[492],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [91] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[665],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[516],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [92] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[551],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[519],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [93] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[555],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[399],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [94] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[557],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[537],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [95] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[561],
- /* return matcher indices */ &kMatcherIndices[16],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[115],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [96] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[565],
- /* return matcher indices */ &kMatcherIndices[16],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[940],
+ /* return matcher indices */ &kMatcherIndices[115],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [97] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[1],
- /* parameters */ &kParameters[569],
- /* return matcher indices */ &kMatcherIndices[47],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[941],
+ /* return matcher indices */ &kMatcherIndices[115],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [98] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[1],
- /* parameters */ &kParameters[573],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[531],
+ /* return matcher indices */ &kMatcherIndices[115],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [99] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 3,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[0],
- /* parameters */ &kParameters[575],
- /* return matcher indices */ &kMatcherIndices[28],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[763],
+ /* return matcher indices */ &kMatcherIndices[115],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [100] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[425],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[765],
+ /* return matcher indices */ &kMatcherIndices[115],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [101] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[422],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[2],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[945],
+ /* return matcher indices */ &kMatcherIndices[121],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [102] */
- /* num parameters */ 4,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[294],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[4],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[946],
+ /* return matcher indices */ &kMatcherIndices[123],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [103] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[416],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[6],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[947],
+ /* return matcher indices */ &kMatcherIndices[125],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [104] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[413],
- /* return matcher indices */ &kMatcherIndices[105],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[0],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[948],
+ /* return matcher indices */ &kMatcherIndices[127],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [105] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[410],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[856],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [106] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[286],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[855],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [107] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[386],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[854],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [108] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[493],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[853],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [109] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[103],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[852],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [110] */
- /* num parameters */ 6,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[67],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[851],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [111] */
- /* num parameters */ 6,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[7],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[850],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [112] */
- /* num parameters */ 7,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[0],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[849],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [113] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[93],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[848],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [114] */
- /* num parameters */ 6,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[43],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* 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[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [115] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[143],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[540],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [116] */
- /* num parameters */ 6,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[25],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[543],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [117] */
/* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[346],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[323],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [118] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[88],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[573],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [119] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[113],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[576],
+ /* return matcher indices */ &kMatcherIndices[49],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [120] */
- /* num parameters */ 6,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[55],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[579],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [121] */
/* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[270],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[407],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [122] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[73],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[588],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [123] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[266],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[727],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [124] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[123],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[685],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [125] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[4],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[755],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[681],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [126] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[4],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[756],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[679],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [127] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[521],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[673],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [128] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[523],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[671],
+ /* return matcher indices */ &kMatcherIndices[11],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [129] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[525],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[669],
+ /* return matcher indices */ &kMatcherIndices[11],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [130] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[527],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[1],
+ /* parameters */ &kParameters[667],
+ /* return matcher indices */ &kMatcherIndices[76],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [131] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[529],
- /* return matcher indices */ &kMatcherIndices[16],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[1],
+ /* parameters */ &kParameters[665],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [132] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[246],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 3,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[0],
+ /* parameters */ &kParameters[663],
+ /* return matcher indices */ &kMatcherIndices[27],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [133] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[153],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[331],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [134] */
/* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[138],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[180],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [135] */
- /* num parameters */ 6,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[37],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[290],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [136] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[262],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[132],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [137] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[118],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[315],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [138] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[258],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[250],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [139] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[188],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[307],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [140] */
/* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[98],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[270],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [141] */
- /* num parameters */ 6,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[13],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[240],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [142] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[238],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[84],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [143] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[163],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[102],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [144] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[242],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 7,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[65],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [145] */
/* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[158],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[220],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [146] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[83],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[114],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [147] */
- /* num parameters */ 6,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[61],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[210],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [148] */
- /* num parameters */ 4,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[254],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[120],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [149] */
- /* num parameters */ 5,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[133],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[105],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [150] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[531],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[932],
+ /* return matcher indices */ &kMatcherIndices[105],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [151] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[535],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[933],
+ /* return matcher indices */ &kMatcherIndices[105],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [152] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[539],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[12],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[759],
+ /* return matcher indices */ &kMatcherIndices[105],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [153] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[543],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[2],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[935],
+ /* return matcher indices */ &kMatcherIndices[103],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [154] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[547],
- /* return matcher indices */ &kMatcherIndices[16],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[4],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[936],
+ /* return matcher indices */ &kMatcherIndices[109],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [155] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[684],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[6],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[937],
+ /* return matcher indices */ &kMatcherIndices[111],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [156] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[683],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 2,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[0],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[938],
+ /* return matcher indices */ &kMatcherIndices[113],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [157] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[682],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[391],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [158] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[681],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[205],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [159] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[3],
- /* parameters */ &kParameters[680],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[185],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [160] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[587],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[138],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [161] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[589],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[375],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [162] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[591],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[160],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [163] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[593],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[303],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [164] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[609],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[265],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [165] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[613],
- /* return matcher indices */ &kMatcherIndices[35],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[260],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [166] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[615],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[144],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [167] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[663],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[311],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [168] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[617],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[245],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [169] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[619],
- /* return matcher indices */ &kMatcherIndices[35],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[299],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [170] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[621],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[280],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [171] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[623],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[285],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [172] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[577],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[108],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [173] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[579],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[295],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [174] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[583],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 5,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[275],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [175] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[585],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[149],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [176] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[401],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[9],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[969],
+ /* return matcher indices */ &kMatcherIndices[149],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [177] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[404],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[970],
+ /* return matcher indices */ &kMatcherIndices[151],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [178] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[407],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[90],
+ /* return matcher indices */ &kMatcherIndices[151],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [179] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[3],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[464],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[781],
+ /* return matcher indices */ &kMatcherIndices[151],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [180] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[3],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[467],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[165],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [181] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[3],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[470],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[9],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[988],
+ /* return matcher indices */ &kMatcherIndices[165],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [182] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[766],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[983],
+ /* return matcher indices */ &kMatcherIndices[167],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [183] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[765],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 12,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[16],
+ /* return matcher indices */ &kMatcherIndices[167],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [184] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[781],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[468],
+ /* return matcher indices */ &kMatcherIndices[167],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [185] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[780],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[169],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [186] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[779],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[9],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[968],
+ /* return matcher indices */ &kMatcherIndices[169],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [187] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[778],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[957],
+ /* return matcher indices */ &kMatcherIndices[171],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [188] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[809],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 8,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[57],
+ /* return matcher indices */ &kMatcherIndices[171],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [189] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[777],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[431],
+ /* return matcher indices */ &kMatcherIndices[171],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [190] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[776],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [191] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[775],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[9],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[964],
+ /* return matcher indices */ &kMatcherIndices[4],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [192] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[774],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[965],
+ /* return matcher indices */ &kMatcherIndices[147],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [193] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[773],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[427],
+ /* return matcher indices */ &kMatcherIndices[147],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [194] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[772],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[779],
+ /* return matcher indices */ &kMatcherIndices[147],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [195] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[771],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[157],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [196] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[770],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[9],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[979],
+ /* return matcher indices */ &kMatcherIndices[157],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [197] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[769],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[980],
+ /* return matcher indices */ &kMatcherIndices[159],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [198] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[3],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[633],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 6,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[78],
+ /* return matcher indices */ &kMatcherIndices[159],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [199] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[3],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[639],
- /* return matcher indices */ &kMatcherIndices[35],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[474],
+ /* return matcher indices */ &kMatcherIndices[159],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [200] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[3],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[629],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[153],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [201] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[3],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[631],
- /* return matcher indices */ &kMatcherIndices[35],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[9],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[974],
+ /* return matcher indices */ &kMatcherIndices[153],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [202] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[768],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[975],
+ /* return matcher indices */ &kMatcherIndices[155],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [203] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[767],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 8,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[49],
+ /* return matcher indices */ &kMatcherIndices[155],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [204] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[783],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* return matcher indices */ &kMatcherIndices[155],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [205] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[782],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[867],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [206] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[764],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[866],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [207] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[763],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[865],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [208] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[359],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[864],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [209] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[356],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[3],
+ /* parameters */ &kParameters[857],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [210] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[762],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[173],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [211] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[761],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[9],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[931],
+ /* return matcher indices */ &kMatcherIndices[173],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [212] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[760],
- /* return matcher indices */ &kMatcherIndices[152],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[928],
+ /* return matcher indices */ &kMatcherIndices[175],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [213] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[759],
- /* return matcher indices */ &kMatcherIndices[137],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 12,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[28],
+ /* return matcher indices */ &kMatcherIndices[175],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [214] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[758],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[435],
+ /* return matcher indices */ &kMatcherIndices[175],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [215] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[757],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[695],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [216] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[750],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[693],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [217] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[749],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[691],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [218] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[748],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[689],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [219] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[747],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[687],
+ /* return matcher indices */ &kMatcherIndices[11],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [220] */
- /* num parameters */ 4,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[338],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[705],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [221] */
- /* num parameters */ 4,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[310],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[703],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [222] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[746],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* 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),
},
{
/* [223] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[745],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[699],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [224] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[507],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[697],
+ /* return matcher indices */ &kMatcherIndices[11],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [225] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[509],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[183],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [226] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[641],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[9],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[919],
+ /* return matcher indices */ &kMatcherIndices[183],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [227] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[643],
- /* return matcher indices */ &kMatcherIndices[35],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[912],
+ /* return matcher indices */ &kMatcherIndices[137],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [228] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[742],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 16,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[0],
+ /* return matcher indices */ &kMatcherIndices[137],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [229] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[741],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 4,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[443],
+ /* return matcher indices */ &kMatcherIndices[137],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [230] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[739],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[161],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [231] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[738],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[9],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[984],
+ /* return matcher indices */ &kMatcherIndices[161],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [232] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[491],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[985],
+ /* return matcher indices */ &kMatcherIndices[163],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [233] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[581],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 9,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[40],
+ /* return matcher indices */ &kMatcherIndices[163],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [234] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[645],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[10],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[471],
+ /* return matcher indices */ &kMatcherIndices[163],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [235] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[647],
- /* return matcher indices */ &kMatcherIndices[35],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[633],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [236] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[649],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[629],
+ /* return matcher indices */ &kMatcherIndices[40],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [237] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[651],
- /* return matcher indices */ &kMatcherIndices[35],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[625],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [238] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[736],
- /* return matcher indices */ &kMatcherIndices[151],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[621],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [239] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[735],
- /* return matcher indices */ &kMatcherIndices[115],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[653],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [240] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[603],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[651],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [241] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[601],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[647],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [242] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[653],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[643],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [243] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[655],
- /* return matcher indices */ &kMatcherIndices[35],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[661],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [244] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[605],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[659],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [245] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[607],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[657],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [246] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[786],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[655],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [247] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[785],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[617],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [248] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[744],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[613],
+ /* return matcher indices */ &kMatcherIndices[40],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [249] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[743],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[609],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [250] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[737],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[607],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [251] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[702],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [252] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[485],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[920],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [253] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[483],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[18],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[921],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [254] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[728],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [255] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[727],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[929],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [256] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[788],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[15],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[930],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [257] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[787],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[522],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [258] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[790],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[525],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [259] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[789],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[528],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [260] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[726],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [261] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[725],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[923],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [262] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[724],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[17],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[924],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [263] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[723],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [264] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[489],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[926],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [265] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[487],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[16],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[927],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [266] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[722],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[459],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [267] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[721],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[462],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [268] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[720],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* 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),
},
{
/* [269] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[719],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[858],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [270] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[718],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[859],
+ /* return matcher indices */ &kMatcherIndices[40],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [271] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[717],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[871],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [272] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[398],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[872],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [273] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[395],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[869],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [274] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[389],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ true,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[870],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [275] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[383],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ true,
+ /* num parameters */ 4,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[439],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [276] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[716],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* 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),
},
{
/* [277] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[715],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[875],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [278] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[499],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[876],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [279] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[501],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[677],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [280] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[753],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[801],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [281] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[754],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[878],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [282] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[713],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[879],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [283] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[712],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[880],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [284] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[711],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[881],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [285] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[710],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[882],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [286] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[751],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[885],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [287] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[752],
- /* return matcher indices */ &kMatcherIndices[35],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[737],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [288] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[709],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[789],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [289] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[708],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[787],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [290] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[792],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[785],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [291] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[791],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[843],
+ /* return matcher indices */ &kMatcherIndices[200],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [292] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[796],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[868],
+ /* return matcher indices */ &kMatcherIndices[135],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [293] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[795],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[973],
+ /* return matcher indices */ &kMatcherIndices[199],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [294] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[392],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[905],
+ /* return matcher indices */ &kMatcherIndices[117],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [295] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[380],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[841],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [296] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[798],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[842],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [297] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[797],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[561],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [298] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[637],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[567],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [299] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[635],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[873],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [300] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[800],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[874],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [301] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[799],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[838],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [302] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[802],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[839],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [303] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[801],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[836],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [304] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[657],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[837],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [305] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[659],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[834],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [306] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[805],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[835],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [307] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[804],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[773],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [308] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[807],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[771],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [309] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[806],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[956],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [310] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[714],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[955],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [311] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[808],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[495],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [312] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[668],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[498],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [313] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[667],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[831],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [314] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[794],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[833],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [315] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[793],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[954],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [316] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[368],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[953],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [317] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[365],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[944],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [318] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[661],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[943],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [319] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[479],
- /* return matcher indices */ &kMatcherIndices[38],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[829],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [320] */
- /* num parameters */ 0,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[810],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[830],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [321] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[704],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[942],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [322] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[705],
- /* return matcher indices */ &kMatcherIndices[113],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[934],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [323] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[706],
- /* return matcher indices */ &kMatcherIndices[113],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[918],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [324] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[707],
- /* return matcher indices */ &kMatcherIndices[113],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[917],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [325] */
/* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[740],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* 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),
},
{
/* [326] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[495],
- /* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[915],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [327] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[497],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[549],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [328] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[503],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[552],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [329] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[505],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[555],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kIsDeprecated),
},
{
/* [330] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[511],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[558],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kIsDeprecated),
},
{
/* [331] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[513],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[914],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [332] */
- /* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[515],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[913],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [333] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[517],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[745],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [334] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[519],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[743],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [335] */
- /* num parameters */ 3,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[1],
- /* open numbers */ &kOpenNumbers[9],
- /* parameters */ &kParameters[353],
- /* return matcher indices */ &kMatcherIndices[135],
- /* supported_stages */ PipelineStageSet(PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[826],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [336] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 2,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[5],
- /* parameters */ &kParameters[678],
- /* return matcher indices */ &kMatcherIndices[20],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[827],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [337] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[703],
- /* return matcher indices */ &kMatcherIndices[109],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[911],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [338] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[449],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[877],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [339] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[481],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[910],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [340] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[729],
- /* return matcher indices */ &kMatcherIndices[1],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[909],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [341] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[730],
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[755],
/* return matcher indices */ &kMatcherIndices[1],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [342] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[731],
- /* return matcher indices */ &kMatcherIndices[1],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[757],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [343] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[732],
- /* return matcher indices */ &kMatcherIndices[1],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[907],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [344] */
/* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[733],
- /* return matcher indices */ &kMatcherIndices[1],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[906],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [345] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[734],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[751],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [346] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[625],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[753],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [347] */
- /* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[627],
- /* return matcher indices */ &kMatcherIndices[18],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[824],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [348] */
- /* num parameters */ 3,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[362],
- /* return matcher indices */ &kMatcherIndices[32],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[825],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
},
{
/* [349] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[611],
- /* return matcher indices */ &kMatcherIndices[121],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[739],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [350] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[595],
- /* return matcher indices */ &kMatcherIndices[1],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[741],
+ /* return matcher indices */ &kMatcherIndices[40],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [351] */
/* num parameters */ 2,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
- /* parameters */ &kParameters[597],
- /* return matcher indices */ &kMatcherIndices[58],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[733],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [352] */
/* num parameters */ 2,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[0],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[599],
- /* return matcher indices */ &kMatcherIndices[3],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[735],
+ /* return matcher indices */ &kMatcherIndices[40],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [353] */
- /* num parameters */ 1,
- /* num open types */ 0,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[6],
- /* parameters */ &kParameters[784],
- /* return matcher indices */ &kMatcherIndices[15],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* 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[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [354] */
- /* num parameters */ 1,
- /* num open types */ 1,
- /* num open numbers */ 1,
- /* open types */ &kOpenTypes[2],
- /* open numbers */ &kOpenNumbers[8],
- /* parameters */ &kParameters[803],
- /* return matcher indices */ &kMatcherIndices[1],
- /* supported_stages */ PipelineStageSet(PipelineStage::kVertex, PipelineStage::kFragment, PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[729],
+ /* return matcher indices */ &kMatcherIndices[40],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
{
/* [355] */
- /* num parameters */ 0,
- /* num open types */ 0,
- /* num open numbers */ 0,
- /* open types */ &kOpenTypes[5],
- /* open numbers */ &kOpenNumbers[10],
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[675],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [356] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[683],
+ /* return matcher indices */ &kMatcherIndices[40],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [357] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[812],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ },
+ {
+ /* [358] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[823],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ },
+ {
+ /* [359] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[807],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ },
+ {
+ /* [360] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[808],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ },
+ {
+ /* [361] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[805],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ },
+ {
+ /* [362] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[806],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ },
+ {
+ /* [363] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[803],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ },
+ {
+ /* [364] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[804],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ },
+ {
+ /* [365] */
+ /* 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[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [366] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[795],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [367] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[845],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [368] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[844],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [369] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[811],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [370] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
/* parameters */ &kParameters[810],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [371] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[814],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [372] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[813],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [373] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[601],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [374] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[13],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[599],
+ /* return matcher indices */ &kMatcherIndices[40],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [375] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[816],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [376] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[815],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [377] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[818],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [378] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[817],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [379] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[820],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [380] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[819],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [381] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[822],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [382] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[821],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [383] */
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[453],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [384] */
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[450],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [385] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[832],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [386] */
+ /* 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::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [387] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[731],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [388] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[761],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [389] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[639],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [390] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[635],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [391] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[966],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [392] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[952],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [393] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[976],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [394] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[971],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [395] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[978],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [396] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[986],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [397] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[939],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [398] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[949],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [399] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[922],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [400] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[925],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [401] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[19],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[862],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [402] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[19],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[863],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [403] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[860],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [404] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[861],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [405] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[963],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [406] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[900],
+ /* return matcher indices */ &kMatcherIndices[37],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [407] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[747],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [408] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[749],
+ /* return matcher indices */ &kMatcherIndices[40],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [409] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[904],
+ /* return matcher indices */ &kMatcherIndices[103],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [410] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[711],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [411] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[713],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [412] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[715],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [413] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[717],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [414] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[719],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [415] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[721],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [416] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[723],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [417] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[725],
/* return matcher indices */ nullptr,
- /* supported_stages */ PipelineStageSet(PipelineStage::kCompute),
- /* is_deprecated */ false,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [418] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[847],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [419] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[605],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [420] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[603],
+ /* return matcher indices */ &kMatcherIndices[21],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [421] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[967],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [422] */
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [423] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[901],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [424] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[902],
+ /* return matcher indices */ &kMatcherIndices[45],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [425] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[903],
+ /* return matcher indices */ &kMatcherIndices[103],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [426] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[709],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [427] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[987],
+ /* return matcher indices */ &kMatcherIndices[103],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [428] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 2,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[5],
+ /* parameters */ &kParameters[908],
+ /* return matcher indices */ &kMatcherIndices[23],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [429] */
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[990],
+ /* return matcher indices */ nullptr,
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [430] */
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[507],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [431] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[767],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [432] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[989],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [433] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[958],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [434] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[972],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [435] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[977],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [436] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[982],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [437] */
+ /* num parameters */ 3,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[504],
+ /* return matcher indices */ &kMatcherIndices[31],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [438] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[597],
+ /* return matcher indices */ &kMatcherIndices[62],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [439] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[799],
+ /* return matcher indices */ &kMatcherIndices[44],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [440] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[8],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[797],
+ /* return matcher indices */ &kMatcherIndices[1],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [441] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[6],
+ /* parameters */ &kParameters[809],
+ /* return matcher indices */ &kMatcherIndices[5],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [442] */
+ /* num parameters */ 2,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[20],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[791],
+ /* return matcher indices */ &kMatcherIndices[121],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ },
+ {
+ /* [443] */
+ /* num parameters */ 1,
+ /* 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),
+ },
+ {
+ /* [444] */
+ /* num parameters */ 3,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[11],
+ /* template numbers */ &kTemplateNumbers[9],
+ /* parameters */ &kParameters[591],
+ /* return matcher indices */ &kMatcherIndices[105],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
},
};
@@ -10250,336 +12537,336 @@
/* fn abs<T : fiu32>(T) -> T */
/* fn abs<N : num, T : fiu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[250],
+ /* overloads */ &kOverloads[405],
},
{
/* [1] */
/* fn acos(f32) -> f32 */
/* fn acos<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[310],
+ /* overloads */ &kOverloads[399],
},
{
/* [2] */
/* fn all(bool) -> bool */
/* fn all<N : num>(vec<N, bool>) -> bool */
/* num overloads */ 2,
- /* overloads */ &kOverloads[308],
+ /* overloads */ &kOverloads[397],
},
{
/* [3] */
/* fn any(bool) -> bool */
/* fn any<N : num>(vec<N, bool>) -> bool */
/* num overloads */ 2,
- /* overloads */ &kOverloads[306],
+ /* overloads */ &kOverloads[395],
},
{
/* [4] */
/* fn arrayLength<T, A : access>(ptr<storage, array<T>, A>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[354],
+ /* overloads */ &kOverloads[443],
},
{
/* [5] */
/* fn asin(f32) -> f32 */
/* fn asin<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[302],
+ /* overloads */ &kOverloads[393],
},
{
/* [6] */
/* fn atan(f32) -> f32 */
/* fn atan<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[300],
+ /* overloads */ &kOverloads[391],
},
{
/* [7] */
/* fn atan2(f32, f32) -> f32 */
/* fn atan2<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[298],
+ /* overloads */ &kOverloads[387],
},
{
/* [8] */
/* fn ceil(f32) -> f32 */
/* fn ceil<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[296],
+ /* overloads */ &kOverloads[385],
},
{
/* [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> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[294],
+ /* overloads */ &kOverloads[383],
},
{
/* [10] */
/* fn cos(f32) -> f32 */
/* fn cos<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[292],
+ /* overloads */ &kOverloads[381],
},
{
/* [11] */
/* fn cosh(f32) -> f32 */
/* fn cosh<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[314],
+ /* overloads */ &kOverloads[379],
},
{
/* [12] */
/* fn countLeadingZeros<T : iu32>(T) -> T */
/* fn countLeadingZeros<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[290],
+ /* overloads */ &kOverloads[377],
},
{
/* [13] */
/* fn countOneBits<T : iu32>(T) -> T */
/* fn countOneBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[258],
+ /* overloads */ &kOverloads[375],
},
{
/* [14] */
/* fn countTrailingZeros<T : iu32>(T) -> T */
/* fn countTrailingZeros<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[256],
+ /* overloads */ &kOverloads[371],
},
{
/* [15] */
/* fn cross(vec3<f32>, vec3<f32>) -> vec3<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[349],
+ /* overloads */ &kOverloads[442],
},
{
/* [16] */
/* fn degrees(f32) -> f32 */
/* fn degrees<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[246],
+ /* overloads */ &kOverloads[369],
},
{
/* [17] */
/* fn determinant<N : num>(mat<N, N, f32>) -> f32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[353],
+ /* overloads */ &kOverloads[441],
},
{
/* [18] */
/* fn distance(f32, f32) -> f32 */
/* fn distance<N : num>(vec<N, f32>, vec<N, f32>) -> f32 */
/* num overloads */ 2,
- /* overloads */ &kOverloads[240],
+ /* overloads */ &kOverloads[365],
},
{
/* [19] */
/* fn dot<N : num, T : fiu32>(vec<N, T>, vec<N, T>) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[352],
+ /* overloads */ &kOverloads[440],
},
{
/* [20] */
/* fn dot4I8Packed(u32, u32) -> i32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[351],
+ /* overloads */ &kOverloads[439],
},
{
/* [21] */
/* fn dot4U8Packed(u32, u32) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[350],
+ /* overloads */ &kOverloads[438],
},
{
/* [22] */
/* fn dpdx(f32) -> f32 */
/* fn dpdx<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[204],
+ /* overloads */ &kOverloads[363],
},
{
/* [23] */
/* fn dpdxCoarse(f32) -> f32 */
/* fn dpdxCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[184],
+ /* overloads */ &kOverloads[361],
},
{
/* [24] */
/* fn dpdxFine(f32) -> f32 */
/* fn dpdxFine<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[186],
+ /* overloads */ &kOverloads[359],
},
{
/* [25] */
/* fn dpdy(f32) -> f32 */
/* fn dpdy<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[188],
+ /* overloads */ &kOverloads[357],
},
{
/* [26] */
/* fn dpdyCoarse(f32) -> f32 */
/* fn dpdyCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[190],
+ /* overloads */ &kOverloads[347],
},
{
/* [27] */
/* fn dpdyFine(f32) -> f32 */
/* fn dpdyFine<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[192],
+ /* overloads */ &kOverloads[335],
},
{
/* [28] */
/* fn exp(f32) -> f32 */
/* fn exp<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[194],
+ /* overloads */ &kOverloads[319],
},
{
/* [29] */
/* fn exp2(f32) -> f32 */
/* fn exp2<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[196],
+ /* overloads */ &kOverloads[313],
},
{
/* [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[316],
+ /* overloads */ &kOverloads[311],
},
{
/* [31] */
/* fn faceForward<N : num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[348],
+ /* overloads */ &kOverloads[437],
},
{
/* [32] */
/* fn firstLeadingBit<T : iu32>(T) -> T */
/* fn firstLeadingBit<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[202],
+ /* overloads */ &kOverloads[305],
},
{
/* [33] */
/* fn firstTrailingBit<T : iu32>(T) -> T */
/* fn firstTrailingBit<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[182],
+ /* overloads */ &kOverloads[303],
},
{
/* [34] */
/* fn floor(f32) -> f32 */
/* fn floor<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[206],
+ /* overloads */ &kOverloads[301],
},
{
/* [35] */
/* 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[208],
+ /* overloads */ &kOverloads[297],
},
{
/* [36] */
/* fn fract(f32) -> f32 */
/* fn fract<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[210],
+ /* overloads */ &kOverloads[295],
},
{
/* [37] */
/* fn frexp(f32) -> __frexp_result */
/* fn frexp<N : num>(vec<N, f32>) -> __frexp_result_vec<N> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[212],
+ /* overloads */ &kOverloads[291],
},
{
/* [38] */
/* fn fwidth(f32) -> f32 */
/* fn fwidth<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[214],
+ /* overloads */ &kOverloads[273],
},
{
/* [39] */
/* fn fwidthCoarse(f32) -> f32 */
/* fn fwidthCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[216],
+ /* overloads */ &kOverloads[271],
},
{
/* [40] */
/* fn fwidthFine(f32) -> f32 */
/* fn fwidthFine<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[218],
+ /* overloads */ &kOverloads[299],
},
{
/* [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[220],
+ /* overloads */ &kOverloads[275],
},
{
/* [42] */
/* fn inverseSqrt(f32) -> f32 */
/* fn inverseSqrt<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[222],
+ /* 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[224],
+ /* overloads */ &kOverloads[279],
},
{
/* [44] */
/* fn length(f32) -> f32 */
/* fn length<N : num>(vec<N, f32>) -> f32 */
/* num overloads */ 2,
- /* overloads */ &kOverloads[248],
+ /* overloads */ &kOverloads[281],
},
{
/* [45] */
/* fn log(f32) -> f32 */
/* fn log<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[228],
+ /* overloads */ &kOverloads[283],
},
{
/* [46] */
/* fn log2(f32) -> f32 */
/* fn log2<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[230],
+ /* 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[232],
+ /* 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[264],
+ /* overloads */ &kOverloads[289],
},
{
/* [49] */
@@ -10587,90 +12874,90 @@
/* 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[176],
+ /* 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[238],
+ /* overloads */ &kOverloads[293],
},
{
/* [51] */
/* fn normalize<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[345],
+ /* overloads */ &kOverloads[436],
},
{
/* [52] */
/* fn pack2x16float(vec2<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[344],
+ /* overloads */ &kOverloads[435],
},
{
/* [53] */
/* fn pack2x16snorm(vec2<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[343],
+ /* overloads */ &kOverloads[434],
},
{
/* [54] */
/* fn pack2x16unorm(vec2<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[342],
+ /* overloads */ &kOverloads[421],
},
{
/* [55] */
/* fn pack4x8snorm(vec4<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[341],
+ /* overloads */ &kOverloads[433],
},
{
/* [56] */
/* fn pack4x8unorm(vec4<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[340],
+ /* overloads */ &kOverloads[432],
},
{
/* [57] */
/* fn pow(f32, f32) -> f32 */
/* fn pow<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[252],
+ /* overloads */ &kOverloads[307],
},
{
/* [58] */
/* fn radians(f32) -> f32 */
/* fn radians<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[254],
+ /* overloads */ &kOverloads[309],
},
{
/* [59] */
/* fn reflect<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[339],
+ /* overloads */ &kOverloads[431],
},
{
/* [60] */
/* fn refract<N : num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[338],
+ /* overloads */ &kOverloads[430],
},
{
/* [61] */
/* fn reverseBits<T : iu32>(T) -> T */
/* fn reverseBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[260],
+ /* overloads */ &kOverloads[315],
},
{
/* [62] */
/* fn round(f32) -> f32 */
/* fn round<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[262],
+ /* overloads */ &kOverloads[317],
},
{
/* [63] */
@@ -10678,125 +12965,125 @@
/* 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[179],
+ /* overloads */ &kOverloads[257],
},
{
/* [64] */
/* fn sign(f32) -> f32 */
/* fn sign<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[266],
+ /* overloads */ &kOverloads[321],
},
{
/* [65] */
/* fn sin(f32) -> f32 */
/* fn sin<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[268],
+ /* overloads */ &kOverloads[323],
},
{
/* [66] */
/* fn sinh(f32) -> f32 */
/* fn sinh<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[270],
+ /* 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[272],
+ /* overloads */ &kOverloads[327],
},
{
/* [68] */
/* 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[274],
+ /* overloads */ &kOverloads[329],
},
{
/* [69] */
/* fn sqrt(f32) -> f32 */
/* fn sqrt<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[276],
+ /* overloads */ &kOverloads[331],
},
{
/* [70] */
/* fn step(f32, f32) -> f32 */
/* fn step<N : num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[278],
+ /* overloads */ &kOverloads[333],
},
{
/* [71] */
/* fn storageBarrier() */
/* num overloads */ 1,
- /* overloads */ &kOverloads[320],
+ /* overloads */ &kOverloads[429],
},
{
/* [72] */
/* fn tan(f32) -> f32 */
/* fn tan<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[282],
+ /* overloads */ &kOverloads[337],
},
{
/* [73] */
/* fn tanh(f32) -> f32 */
/* fn tanh<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[284],
+ /* overloads */ &kOverloads[339],
},
{
/* [74] */
/* fn transpose<M : num, N : num>(mat<M, N, f32>) -> mat<N, M, f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[336],
+ /* overloads */ &kOverloads[428],
},
{
/* [75] */
/* fn trunc(f32) -> f32 */
/* fn trunc<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[288],
+ /* overloads */ &kOverloads[343],
},
{
/* [76] */
/* fn unpack2x16float(u32) -> vec2<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[324],
+ /* overloads */ &kOverloads[427],
},
{
/* [77] */
/* fn unpack2x16snorm(u32) -> vec2<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[323],
+ /* overloads */ &kOverloads[409],
},
{
/* [78] */
/* fn unpack2x16unorm(u32) -> vec2<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[322],
+ /* overloads */ &kOverloads[425],
},
{
/* [79] */
/* fn unpack4x8snorm(u32) -> vec4<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[321],
+ /* overloads */ &kOverloads[424],
},
{
/* [80] */
/* fn unpack4x8unorm(u32) -> vec4<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[337],
+ /* overloads */ &kOverloads[423],
},
{
/* [81] */
/* fn workgroupBarrier() */
/* num overloads */ 1,
- /* overloads */ &kOverloads[355],
+ /* overloads */ &kOverloads[422],
},
{
/* [82] */
@@ -10845,7 +13132,7 @@
/* 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[57],
+ /* overloads */ &kOverloads[71],
},
{
/* [84] */
@@ -10856,7 +13143,7 @@
/* 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[144],
+ /* overloads */ &kOverloads[157],
},
{
/* [85] */
@@ -10866,7 +13153,7 @@
/* 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[155],
+ /* overloads */ &kOverloads[205],
},
{
/* [86] */
@@ -10881,14 +13168,14 @@
/* fn textureNumLevels(texture: texture_depth_cube) -> i32 */
/* fn textureNumLevels(texture: texture_depth_cube_array) -> i32 */
/* num overloads */ 10,
- /* overloads */ &kOverloads[81],
+ /* overloads */ &kOverloads[105],
},
{
/* [87] */
/* fn textureNumSamples<T : fiu32>(texture: texture_multisampled_2d<T>) -> i32 */
/* fn textureNumSamples(texture: texture_depth_multisampled_2d) -> i32 */
/* num overloads */ 2,
- /* overloads */ &kOverloads[312],
+ /* overloads */ &kOverloads[367],
},
{
/* [88] */
@@ -10908,7 +13195,7 @@
/* 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[42],
+ /* overloads */ &kOverloads[27],
},
{
/* [89] */
@@ -10921,7 +13208,7 @@
/* 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[117],
+ /* overloads */ &kOverloads[133],
},
{
/* [90] */
@@ -10932,7 +13219,7 @@
/* 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[138],
+ /* overloads */ &kOverloads[169],
},
{
/* [91] */
@@ -10943,7 +13230,7 @@
/* 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[132],
+ /* overloads */ &kOverloads[163],
},
{
/* [92] */
@@ -10956,7 +13243,7 @@
/* 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[109],
+ /* overloads */ &kOverloads[141],
},
{
/* [93] */
@@ -10976,7 +13263,7 @@
/* 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[27],
+ /* overloads */ &kOverloads[42],
},
{
/* [94] */
@@ -10993,7 +13280,7 @@
/* 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[69],
+ /* overloads */ &kOverloads[83],
},
{
/* [95] */
@@ -11007,115 +13294,126 @@
/* 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[100],
+ /* overloads */ &kOverloads[115],
},
{
/* [96] */
/* fn atomicLoad<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[325],
+ /* overloads */ &kOverloads[418],
},
{
/* [97] */
/* fn atomicStore<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) */
/* num overloads */ 1,
- /* overloads */ &kOverloads[326],
+ /* overloads */ &kOverloads[417],
},
{
/* [98] */
/* fn atomicAdd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[327],
+ /* overloads */ &kOverloads[416],
},
{
/* [99] */
/* fn atomicSub<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[328],
+ /* overloads */ &kOverloads[415],
},
{
/* [100] */
/* fn atomicMax<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[329],
+ /* overloads */ &kOverloads[414],
},
{
/* [101] */
/* fn atomicMin<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[330],
+ /* overloads */ &kOverloads[413],
},
{
/* [102] */
/* fn atomicAnd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[331],
+ /* overloads */ &kOverloads[412],
},
{
/* [103] */
/* fn atomicOr<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[332],
+ /* overloads */ &kOverloads[411],
},
{
/* [104] */
/* fn atomicXor<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[333],
+ /* overloads */ &kOverloads[410],
},
{
/* [105] */
/* fn atomicExchange<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[334],
+ /* overloads */ &kOverloads[426],
},
{
/* [106] */
/* fn atomicCompareExchangeWeak<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> vec2<T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[335],
+ /* overloads */ &kOverloads[444],
},
};
-constexpr IntrinsicInfo kOperators[] = {
+constexpr IntrinsicInfo kUnaryOperators[] = {
{
/* [0] */
/* op !(bool) -> bool */
/* op !<N : num>(vec<N, bool>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[286],
+ /* overloads */ &kOverloads[269],
},
{
/* [1] */
/* op ~<T : iu32>(T) -> T */
/* op ~<T : iu32, N : num>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[280],
+ /* overloads */ &kOverloads[403],
},
{
/* [2] */
/* op -<T : fi32>(T) -> T */
/* op -<T : fi32, N : num>(vec<N, T>) -> vec<N, T> */
- /* op -<T : fiu32>(T, T) -> T */
- /* op -<T : fiu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
- /* op -<T : fiu32, N : num>(vec<N, T>, T) -> vec<N, T> */
- /* 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 */ 7,
- /* overloads */ &kOverloads[125],
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[401],
},
+};
+constexpr uint8_t kUnaryOperatorNot = 0;
+constexpr uint8_t kUnaryOperatorComplement = 1;
+constexpr uint8_t kUnaryOperatorMinus = 2;
+
+constexpr IntrinsicInfo kBinaryOperators[] = {
{
- /* [3] */
+ /* [0] */
/* op +<T : fiu32>(T, T) -> T */
/* op +<T : fiu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* op +<T : fiu32, N : num>(vec<N, T>, T) -> vec<N, T> */
/* 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[150],
+ /* overloads */ &kOverloads[220],
},
{
- /* [4] */
+ /* [1] */
+ /* op -<T : fiu32>(T, T) -> T */
+ /* op -<T : fiu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
+ /* op -<T : fiu32, N : num>(vec<N, T>, T) -> vec<N, T> */
+ /* 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],
+ },
+ {
+ /* [2] */
/* op *<T : fiu32>(T, T) -> T */
/* op *<T : fiu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* op *<T : fiu32, N : num>(vec<N, T>, T) -> vec<N, T> */
@@ -11126,139 +13424,309 @@
/* 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[91],
+ /* overloads */ &kOverloads[124],
},
{
- /* [5] */
+ /* [3] */
/* op /<T : fiu32>(T, T) -> T */
/* op /<T : fiu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* 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[172],
+ /* overloads */ &kOverloads[243],
},
{
- /* [6] */
+ /* [4] */
/* op %<T : fiu32>(T, T) -> T */
/* op %<T : fiu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* 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[160],
+ /* overloads */ &kOverloads[239],
},
{
- /* [7] */
+ /* [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[244],
+ /* overloads */ &kOverloads[389],
},
{
- /* [8] */
+ /* [6] */
/* op &(bool, bool) -> bool */
/* op &<N : num>(vec<N, bool>, vec<N, bool>) -> vec<N, bool> */
/* 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[164],
+ /* overloads */ &kOverloads[235],
},
{
- /* [9] */
+ /* [7] */
/* op |(bool, bool) -> bool */
/* op |<N : num>(vec<N, bool>, vec<N, bool>) -> vec<N, bool> */
/* 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[168],
+ /* overloads */ &kOverloads[247],
+ },
+ {
+ /* [8] */
+ /* op &&(bool, bool) -> bool */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[419],
+ },
+ {
+ /* [9] */
+ /* op ||(bool, bool) -> bool */
+ /* num overloads */ 1,
+ /* overloads */ &kOverloads[420],
},
{
/* [10] */
- /* op &&(bool, bool) -> bool */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[346],
- },
- {
- /* [11] */
- /* op ||(bool, bool) -> bool */
- /* num overloads */ 1,
- /* overloads */ &kOverloads[347],
- },
- {
- /* [12] */
/* 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[200],
+ /* overloads */ &kOverloads[373],
},
{
- /* [13] */
+ /* [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[198],
+ /* overloads */ &kOverloads[355],
},
{
- /* [14] */
+ /* [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[226],
+ /* overloads */ &kOverloads[353],
},
{
- /* [15] */
+ /* [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[234],
+ /* overloads */ &kOverloads[351],
},
{
- /* [16] */
+ /* [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[236],
+ /* overloads */ &kOverloads[349],
},
{
- /* [17] */
+ /* [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[242],
+ /* overloads */ &kOverloads[407],
},
{
- /* [18] */
+ /* [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[304],
+ /* overloads */ &kOverloads[345],
},
{
- /* [19] */
+ /* [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[318],
+ /* overloads */ &kOverloads[341],
},
};
-constexpr uint8_t kOperatorNot = 0;
-constexpr uint8_t kOperatorComplement = 1;
-constexpr uint8_t kOperatorMinus = 2;
-constexpr uint8_t kOperatorPlus = 3;
-constexpr uint8_t kOperatorStar = 4;
-constexpr uint8_t kOperatorDivide = 5;
-constexpr uint8_t kOperatorModulo = 6;
-constexpr uint8_t kOperatorXor = 7;
-constexpr uint8_t kOperatorAnd = 8;
-constexpr uint8_t kOperatorOr = 9;
-constexpr uint8_t kOperatorLogicalAnd = 10;
-constexpr uint8_t kOperatorLogicalOr = 11;
-constexpr uint8_t kOperatorEqual = 12;
-constexpr uint8_t kOperatorNotEqual = 13;
-constexpr uint8_t kOperatorLessThan = 14;
-constexpr uint8_t kOperatorGreaterThan = 15;
-constexpr uint8_t kOperatorLessThanEqual = 16;
-constexpr uint8_t kOperatorGreaterThanEqual = 17;
-constexpr uint8_t kOperatorShiftLeft = 18;
-constexpr uint8_t kOperatorShiftRight = 19;
+constexpr uint8_t kBinaryOperatorPlus = 0;
+constexpr uint8_t kBinaryOperatorMinus = 1;
+constexpr uint8_t kBinaryOperatorStar = 2;
+constexpr uint8_t kBinaryOperatorDivide = 3;
+constexpr uint8_t kBinaryOperatorModulo = 4;
+constexpr uint8_t kBinaryOperatorXor = 5;
+constexpr uint8_t kBinaryOperatorAnd = 6;
+constexpr uint8_t kBinaryOperatorOr = 7;
+constexpr uint8_t kBinaryOperatorLogicalAnd = 8;
+constexpr uint8_t kBinaryOperatorLogicalOr = 9;
+constexpr uint8_t kBinaryOperatorEqual = 10;
+constexpr uint8_t kBinaryOperatorNotEqual = 11;
+constexpr uint8_t kBinaryOperatorLessThan = 12;
+constexpr uint8_t kBinaryOperatorGreaterThan = 13;
+constexpr uint8_t kBinaryOperatorLessThanEqual = 14;
+constexpr uint8_t kBinaryOperatorGreaterThanEqual = 15;
+constexpr uint8_t kBinaryOperatorShiftLeft = 16;
+constexpr uint8_t kBinaryOperatorShiftRight = 17;
+
+constexpr IntrinsicInfo kConstructorsAndConverters[] = {
+ {
+ /* [0] */
+ /* ctor i32() -> i32 */
+ /* ctor i32(i32) -> i32 */
+ /* conv i32<T : scalar_no_i32>(T) -> i32 */
+ /* num overloads */ 3,
+ /* overloads */ &kOverloads[251],
+ },
+ {
+ /* [1] */
+ /* ctor u32() -> u32 */
+ /* ctor u32(u32) -> u32 */
+ /* conv u32<T : scalar_no_u32>(T) -> u32 */
+ /* num overloads */ 3,
+ /* overloads */ &kOverloads[260],
+ },
+ {
+ /* [2] */
+ /* ctor f32() -> f32 */
+ /* ctor f32(f32) -> f32 */
+ /* conv f32<T : scalar_no_f32>(T) -> f32 */
+ /* num overloads */ 3,
+ /* overloads */ &kOverloads[263],
+ },
+ {
+ /* [3] */
+ /* ctor bool() -> bool */
+ /* ctor bool(bool) -> bool */
+ /* conv bool<T : scalar_no_bool>(T) -> bool */
+ /* num overloads */ 3,
+ /* overloads */ &kOverloads[254],
+ },
+ {
+ /* [4] */
+ /* 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 : 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],
+ },
+ {
+ /* [5] */
+ /* ctor vec3<T : scalar>() -> vec3<T> */
+ /* ctor vec3<T : scalar>(vec3<T>) -> vec3<T> */
+ /* ctor vec3<T : abstract_or_scalar>(T) -> vec3<T> */
+ /* ctor vec3<T : abstract_or_scalar>(x: T, y: T, z: T) -> vec3<T> */
+ /* 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 : 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],
+ },
+ {
+ /* [6] */
+ /* ctor vec4<T : scalar>() -> vec4<T> */
+ /* ctor vec4<T : scalar>(vec4<T>) -> vec4<T> */
+ /* ctor vec4<T : abstract_or_scalar>(T) -> vec4<T> */
+ /* ctor vec4<T : abstract_or_scalar>(x: T, y: T, z: T, w: T) -> vec4<T> */
+ /* ctor vec4<T : abstract_or_scalar>(xy: vec2<T>, z: T, w: T) -> vec4<T> */
+ /* ctor vec4<T : abstract_or_scalar>(x: T, yz: vec2<T>, w: T) -> vec4<T> */
+ /* ctor vec4<T : abstract_or_scalar>(x: T, y: T, zw: vec2<T>) -> vec4<T> */
+ /* ctor vec4<T : abstract_or_scalar>(xy: vec2<T>, zw: vec2<T>) -> vec4<T> */
+ /* 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 : 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],
+ },
+ {
+ /* [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[175],
+ },
+ {
+ /* [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[200],
+ },
+ {
+ /* [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[195],
+ },
+ {
+ /* [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,
+ /* overloads */ &kOverloads[230],
+ },
+ {
+ /* [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[180],
+ },
+ {
+ /* [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[185],
+ },
+ {
+ /* [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[210],
+ },
+ {
+ /* [15] */
+ /* ctor mat4x4() -> mat4x4<f32> */
+ /* ctor mat4x4<f32>(mat4x4<f32>) -> mat4x4<f32> */
+ /* 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[225],
+ },
+};
// clang-format on
diff --git a/src/tint/resolver/intrinsic_table.inl.tmpl b/src/tint/resolver/intrinsic_table.inl.tmpl
index 9eeaebc..f5e3575 100644
--- a/src/tint/resolver/intrinsic_table.inl.tmpl
+++ b/src/tint/resolver/intrinsic_table.inl.tmpl
@@ -51,8 +51,8 @@
{{- end }}
};
-constexpr OpenTypeInfo kOpenTypes[] = {
-{{- range $i, $o := .OpenTypes }}
+constexpr TemplateTypeInfo kTemplateTypes[] = {
+{{- range $i, $o := .TemplateTypes }}
{
/* [{{$i}}] */
/* name */ "{{$o.Name}}",
@@ -64,8 +64,8 @@
{{- end }}
};
-constexpr OpenNumberInfo kOpenNumbers[] = {
-{{- range $i, $o := .OpenNumbers }}
+constexpr TemplateNumberInfo kTemplateNumbers[] = {
+{{- range $i, $o := .TemplateNumbers }}
{
/* [{{$i}}] */
/* name */ "{{$o.Name}}",
@@ -82,14 +82,14 @@
{
/* [{{$i}}] */
/* num parameters */ {{$o.NumParameters}},
- /* num open types */ {{$o.NumOpenTypes}},
- /* num open numbers */ {{$o.NumOpenNumbers}},
- /* open types */
-{{- if $o.OpenTypesOffset }} &kOpenTypes[{{$o.OpenTypesOffset}}],
+ /* num template types */ {{$o.NumTemplateTypes}},
+ /* num template numbers */ {{$o.NumTemplateNumbers}},
+ /* template types */
+{{- if $o.TemplateTypesOffset }} &kTemplateTypes[{{$o.TemplateTypesOffset}}],
{{- else }} nullptr,
{{- end }}
- /* open numbers */
-{{- if $o.OpenNumbersOffset }} &kOpenNumbers[{{$o.OpenNumbersOffset}}]
+ /* template numbers */
+{{- if $o.TemplateNumbersOffset }} &kTemplateNumbers[{{$o.TemplateNumbersOffset}}]
{{- else }} nullptr
{{- end }},
/* parameters */ &kParameters[{{$o.ParametersOffset}}],
@@ -97,11 +97,11 @@
{{- if $o.ReturnMatcherIndicesOffset }} &kMatcherIndices[{{$o.ReturnMatcherIndicesOffset}}]
{{- else }} nullptr
{{- end }},
- /* supported_stages */ PipelineStageSet(
+ /* flags */ OverloadFlags(OverloadFlag::kIs{{Title $o.Kind}}
{{- range $i, $u := $o.CanBeUsedInStage.List -}}
-{{- if $i -}}, {{end}}PipelineStage::k{{Title $u}}
-{{- end }}),
- /* is_deprecated */ {{$o.IsDeprecated}},
+ , OverloadFlag::kSupports{{Title $u}}Pipeline
+{{- end }}
+{{- if $o.IsDeprecated}}, OverloadFlag::kIsDeprecated{{end }}),
},
{{- end }}
};
@@ -119,8 +119,8 @@
{{- end }}
};
-constexpr IntrinsicInfo kOperators[] = {
-{{- range $i, $o := .Operators }}
+constexpr IntrinsicInfo kUnaryOperators[] = {
+{{- range $i, $o := .UnaryOperators }}
{
/* [{{$i}}] */
{{- range $o.OverloadDescriptions }}
@@ -132,10 +132,40 @@
{{- end }}
};
-{{- range $i, $o := .Operators }}
-constexpr uint8_t kOperator{{template "OperatorName" $o.Name}} = {{$i}};
+{{- range $i, $o := .UnaryOperators }}
+constexpr uint8_t kUnaryOperator{{template "OperatorName" $o.Name}} = {{$i}};
{{- end }}
+constexpr IntrinsicInfo kBinaryOperators[] = {
+{{- range $i, $o := .BinaryOperators }}
+ {
+ /* [{{$i}}] */
+{{- range $o.OverloadDescriptions }}
+ /* {{.}} */
+{{- end }}
+ /* num overloads */ {{$o.NumOverloads}},
+ /* overloads */ &kOverloads[{{$o.OverloadsOffset}}],
+ },
+{{- end }}
+};
+
+{{- range $i, $o := .BinaryOperators }}
+constexpr uint8_t kBinaryOperator{{template "OperatorName" $o.Name}} = {{$i}};
+{{- end }}
+
+constexpr IntrinsicInfo kConstructorsAndConverters[] = {
+{{- range $i, $o := .ConstructorsAndConverters }}
+ {
+ /* [{{$i}}] */
+{{- range $o.OverloadDescriptions }}
+ /* {{.}} */
+{{- end }}
+ /* num overloads */ {{$o.NumOverloads}},
+ /* overloads */ &kOverloads[{{$o.OverloadsOffset}}],
+ },
+{{- end }}
+};
+
// clang-format on
{{ end -}}
@@ -150,7 +180,7 @@
class {{$class}} : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -158,7 +188,7 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* {{$class}}::Match(MatchState& state, const sem::Type* ty) const {
@@ -177,7 +207,7 @@
return build_{{TrimLeft .Name "_"}}(state{{range .TemplateParams}}, {{.GetName}}{{end}});
}
-std::string {{$class}}::String(MatchState&{{if .TemplateParams}} state{{end}}) const {
+std::string {{$class}}::String(MatchState*{{if .TemplateParams}} state{{end}}) const {
{{- range .TemplateParams }}
{{- template "DeclareLocalTemplateParamName" . }}
{{- end }}
@@ -206,7 +236,7 @@
public:
/// Checks whether the given type matches the matcher rules, and returns the
/// expected, canonicalized type on success.
- /// Match may close open types and numbers in state.
+ /// 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
@@ -214,11 +244,11 @@
const sem::Type* type) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
const sem::Type* {{$class}}::Match(MatchState& state, const sem::Type* ty) const {
-{{- range .Types }}
+{{- range .PrecedenceSortedTypes }}
if (match_{{.Name}}(ty)) {
return build_{{.Name}}(state);
}
@@ -226,15 +256,18 @@
return nullptr;
}
-std::string {{$class}}::String(MatchState&) const {
- return "
+std::string {{$class}}::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
{{- range .Types -}}
-{{- if IsFirstIn . $.Types }}{{.Name}}
-{{- else if IsLastIn . $.Types }} or {{.Name}}
-{{- else }}, {{.Name}}
+{{- if IsFirstIn . $.Types }} << {{PascalCase .Name}}().String(nullptr)
+{{- else if IsLastIn . $.Types }} << " or " << {{PascalCase .Name}}().String(nullptr)
+{{- else }} << ", " << {{PascalCase .Name}}().String(nullptr)
{{- end -}}
-{{- end -}}
- ";
+{{- end -}};
+ return ss.str();
}
{{ end -}}
@@ -250,14 +283,14 @@
class {{$class}} : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
- /// Match may close open types and numbers in state.
+ /// Match may define template numbers in state.
/// @param state the MatchState
/// @param number the enum value as a Number
/// @return true if the enum value matches the set
Number Match(MatchState& state, Number number) const override;
/// @param state the MatchState
/// @return a string representation of the matcher.
- std::string String(MatchState& state) const override;
+ std::string String(MatchState* state) const override;
};
{{ if eq 1 (len .Options) -}}
@@ -282,7 +315,7 @@
}
{{- end }}
-std::string {{$class}}::String(MatchState&) const {
+std::string {{$class}}::String(MatchState*) const {
return "
{{- range .Options -}}
{{- if IsFirstIn . $.Options }}{{.Name}}
@@ -302,15 +335,15 @@
private:
{{- $t_names := Map -}}
{{- $n_names := Map -}}
-{{- range Iterate .Sem.MaxOpenTypes -}}
-{{- $name := printf "open_type_%v" . -}}
+{{- range Iterate .Sem.MaxTemplateTypes -}}
+{{- $name := printf "template_type_%v" . -}}
{{- $t_names.Put . $name }}
- OpenTypeMatcher {{$name}}_{ {{- . -}} };
+ TemplateTypeMatcher {{$name}}_{ {{- . -}} };
{{- end }}
-{{- range Iterate .Sem.MaxOpenNumbers -}}
-{{- $name := printf "open_number_%v" . -}}
+{{- range Iterate .Sem.MaxTemplateNumbers -}}
+{{- $name := printf "template_number_%v" . -}}
{{- $n_names.Put . $name }}
- OpenNumberMatcher {{$name}}_{ {{- . -}} };
+ TemplateNumberMatcher {{$name}}_{ {{- . -}} };
{{- end }}
{{- range .Sem.Types -}}
{{- $name := PascalCase .Name -}}
@@ -334,7 +367,7 @@
/// Destructor
~Matchers();
- /// The open-types, types, and type matchers
+ /// The template types, types, and type matchers
TypeMatcher const* const type[{{len .TMatchers}}] = {
{{- range $i, $m := .TMatchers }}
/* [{{$i}}] */
@@ -344,7 +377,7 @@
{{- end }}
};
- /// The open-numbers, and number matchers
+ /// The template numbers, and number matchers
NumberMatcher const* const number[{{len .NMatchers}}] = {
{{- range $i, $m := .NMatchers }}
/* [{{$i}}] */
@@ -375,11 +408,11 @@
{{- define "DeclareLocalTemplateParamName" -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{- if IsTemplateTypeParam . }}
- const std::string {{.Name}} = state.TypeName();
+ const std::string {{.Name}} = state->TypeName();
{{- else if IsTemplateNumberParam . }}
- const std::string {{.Name}} = state.NumName();
+ const std::string {{.Name}} = state->NumName();
{{- else if IsTemplateEnumParam . }}
- const std::string {{.Name}} = state.NumName();
+ const std::string {{.Name}} = state->NumName();
{{- end -}}
{{- end -}}
diff --git a/src/tint/resolver/intrinsic_table_test.cc b/src/tint/resolver/intrinsic_table_test.cc
index 79d1a53..4a5c171 100644
--- a/src/tint/resolver/intrinsic_table_test.cc
+++ b/src/tint/resolver/intrinsic_table_test.cc
@@ -14,8 +14,11 @@
#include "src/tint/resolver/intrinsic_table.h"
+#include <utility>
+
#include "gmock/gmock.h"
#include "src/tint/program_builder.h"
+#include "src/tint/resolver/resolver_test_helper.h"
#include "src/tint/sem/atomic.h"
#include "src/tint/sem/depth_multisampled_texture.h"
#include "src/tint/sem/depth_texture.h"
@@ -24,8 +27,11 @@
#include "src/tint/sem/reference.h"
#include "src/tint/sem/sampled_texture.h"
#include "src/tint/sem/storage_texture.h"
+#include "src/tint/sem/test_helper.h"
+#include "src/tint/sem/type_constructor.h"
+#include "src/tint/sem/type_conversion.h"
-namespace tint {
+namespace tint::resolver {
namespace {
using ::testing::HasSubstr;
@@ -34,6 +40,12 @@
using Parameter = sem::Parameter;
using ParameterUsage = sem::ParameterUsage;
+using AFloatV = builder::vec<3, AFloat>;
+using AIntV = builder::vec<3, AInt>;
+using f32V = builder::vec<3, f32>;
+using i32V = builder::vec<3, i32>;
+using u32V = builder::vec<3, u32>;
+
class IntrinsicTableTest : public testing::Test, public ProgramBuilder {
public:
std::unique_ptr<IntrinsicTable> table = IntrinsicTable::Create(*this);
@@ -414,7 +426,7 @@
EXPECT_EQ(result->Parameters()[0]->Type(), f32);
}
-TEST_F(IntrinsicTableTest, MatchOpenType) {
+TEST_F(IntrinsicTableTest, MatchTemplateType) {
auto* f32 = create<sem::F32>();
auto* result = table->Lookup(BuiltinType::kClamp, {f32, f32, f32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
@@ -426,7 +438,7 @@
EXPECT_EQ(result->Parameters()[2]->Type(), f32);
}
-TEST_F(IntrinsicTableTest, MismatchOpenType) {
+TEST_F(IntrinsicTableTest, MismatchTemplateType) {
auto* f32 = create<sem::F32>();
auto* u32 = create<sem::U32>();
auto* result = table->Lookup(BuiltinType::kClamp, {f32, u32, f32}, Source{});
@@ -661,5 +673,569 @@
)");
}
+TEST_F(IntrinsicTableTest, MatchTypeConstructorImplicit) {
+ auto* i32 = create<sem::I32>();
+ auto* vec3_i32 = create<sem::Vector>(i32, 3u);
+ auto* result =
+ table->Lookup(CtorConvIntrinsic::kVec3, nullptr, {i32, i32, i32}, Source{{12, 34}});
+ ASSERT_NE(result, nullptr);
+ EXPECT_EQ(result->ReturnType(), vec3_i32);
+ EXPECT_TRUE(result->Is<sem::TypeConstructor>());
+ ASSERT_EQ(result->Parameters().size(), 3u);
+ EXPECT_EQ(result->Parameters()[0]->Type(), i32);
+ EXPECT_EQ(result->Parameters()[1]->Type(), i32);
+ EXPECT_EQ(result->Parameters()[2]->Type(), i32);
+}
+
+TEST_F(IntrinsicTableTest, MatchTypeConstructorExplicit) {
+ auto* i32 = create<sem::I32>();
+ auto* vec3_i32 = create<sem::Vector>(i32, 3u);
+ auto* result = table->Lookup(CtorConvIntrinsic::kVec3, i32, {i32, i32, i32}, Source{{12, 34}});
+ ASSERT_NE(result, nullptr);
+ EXPECT_EQ(result->ReturnType(), vec3_i32);
+ EXPECT_TRUE(result->Is<sem::TypeConstructor>());
+ ASSERT_EQ(result->Parameters().size(), 3u);
+ EXPECT_EQ(result->Parameters()[0]->Type(), i32);
+ EXPECT_EQ(result->Parameters()[1]->Type(), i32);
+ EXPECT_EQ(result->Parameters()[2]->Type(), i32);
+}
+
+TEST_F(IntrinsicTableTest, MismatchTypeConstructorImplicit) {
+ auto* i32 = create<sem::I32>();
+ auto* f32 = create<sem::F32>();
+ auto* result =
+ table->Lookup(CtorConvIntrinsic::kVec3, nullptr, {i32, f32, i32}, Source{{12, 34}});
+ ASSERT_EQ(result, nullptr);
+ 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
+
+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
+)");
+}
+
+TEST_F(IntrinsicTableTest, MismatchTypeConstructorExplicit) {
+ auto* i32 = create<sem::I32>();
+ auto* f32 = create<sem::F32>();
+ auto* result = table->Lookup(CtorConvIntrinsic::kVec3, i32, {i32, f32, i32}, Source{{12, 34}});
+ ASSERT_EQ(result, nullptr);
+ EXPECT_EQ(Diagnostics().str(),
+ 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
+
+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
+)");
+}
+
+TEST_F(IntrinsicTableTest, MatchTypeConversion) {
+ auto* i32 = create<sem::I32>();
+ auto* vec3_i32 = create<sem::Vector>(i32, 3u);
+ auto* f32 = create<sem::F32>();
+ auto* vec3_f32 = create<sem::Vector>(f32, 3u);
+ auto* result = table->Lookup(CtorConvIntrinsic::kVec3, i32, {vec3_f32}, Source{{12, 34}});
+ ASSERT_NE(result, nullptr);
+ EXPECT_EQ(result->ReturnType(), vec3_i32);
+ EXPECT_TRUE(result->Is<sem::TypeConversion>());
+ ASSERT_EQ(result->Parameters().size(), 1u);
+ EXPECT_EQ(result->Parameters()[0]->Type(), vec3_f32);
+}
+
+TEST_F(IntrinsicTableTest, MismatchTypeConversion) {
+ auto* arr = create<sem::Array>(create<sem::U32>(), 0u, 4u, 4u, 4u, 4u);
+ auto* f32 = create<sem::F32>();
+ auto* result = table->Lookup(CtorConvIntrinsic::kVec3, f32, {arr}, Source{{12, 34}});
+ ASSERT_EQ(result, nullptr);
+ EXPECT_EQ(Diagnostics().str(),
+ 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
+
+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
+)");
+}
+
+TEST_F(IntrinsicTableTest, Err257Arguments) { // crbug.com/1323605
+ auto* f32 = create<sem::F32>();
+ std::vector<const sem::Type*> arg_tys(257, f32);
+ auto* result = table->Lookup(BuiltinType::kAbs, std::move(arg_tys), Source{});
+ ASSERT_EQ(result, nullptr);
+ ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AbstractBinaryTests
+////////////////////////////////////////////////////////////////////////////////
+namespace AbstractBinaryTests {
+
+struct Case {
+ template <typename RESULT,
+ typename PARAM_LHS,
+ typename PARAM_RHS,
+ typename ARG_LHS,
+ typename ARG_RHS>
+ static Case Create(bool match = true) {
+ return {
+ match, //
+ builder::DataType<RESULT>::Sem, //
+ builder::DataType<PARAM_LHS>::Sem, //
+ builder::DataType<PARAM_RHS>::Sem, //
+ builder::DataType<ARG_LHS>::Sem, //
+ builder::DataType<ARG_RHS>::Sem, //
+ };
+ }
+ bool expected_match;
+ builder::sem_type_func_ptr expected_result;
+ builder::sem_type_func_ptr expected_param_lhs;
+ builder::sem_type_func_ptr expected_param_rhs;
+ builder::sem_type_func_ptr arg_lhs;
+ builder::sem_type_func_ptr arg_rhs;
+};
+
+struct IntrinsicTableAbstractBinaryTest : public ResolverTestWithParam<Case> {
+ std::unique_ptr<IntrinsicTable> table = IntrinsicTable::Create(*this);
+};
+
+TEST_P(IntrinsicTableAbstractBinaryTest, MatchAdd) {
+ auto* arg_lhs = GetParam().arg_lhs(*this);
+ auto* arg_rhs = GetParam().arg_rhs(*this);
+ auto result = table->Lookup(ast::BinaryOp::kAdd, arg_lhs, arg_rhs, Source{{12, 34}},
+ /* is_compound */ false);
+
+ bool matched = result.result != nullptr;
+ bool expected_match = GetParam().expected_match;
+ EXPECT_EQ(matched, expected_match) << Diagnostics().str();
+
+ auto* expected_result = GetParam().expected_result(*this);
+ EXPECT_TYPE(result.result, expected_result);
+
+ auto* expected_param_lhs = GetParam().expected_param_lhs(*this);
+ EXPECT_TYPE(result.lhs, expected_param_lhs);
+
+ auto* expected_param_rhs = GetParam().expected_param_rhs(*this);
+ EXPECT_TYPE(result.rhs, expected_param_rhs);
+}
+
+INSTANTIATE_TEST_SUITE_P(AFloat_AInt,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<f32, f32, f32, AFloat, AFloat>(),
+Case::Create<f32, f32, f32, AFloat, AInt>(),
+Case::Create<f32, f32, f32, AInt, AFloat>(),
+Case::Create<i32, i32, i32, AInt, AInt>()
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(VecAFloat_VecAInt,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<f32V, f32V, f32V, AFloatV, AFloatV>(),
+Case::Create<f32V, f32V, f32V, AFloatV, AIntV>(),
+Case::Create<f32V, f32V, f32V, AIntV, AFloatV>(),
+Case::Create<i32V, i32V, i32V, AIntV, AIntV>()
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(AFloat_f32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<f32, f32, f32, AFloat, f32>(),
+Case::Create<f32, f32, f32, f32, AFloat>()
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(VecAFloat_Vecf32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<f32V, f32V, f32V, AFloatV, f32V>(),
+Case::Create<f32V, f32V, f32V, f32V, AFloatV>()
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(
+ AFloat_i32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<void, void, void, AFloat, i32>(false),
+Case::Create<void, void, void, i32, AFloat>(false)
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(
+ VecAFloat_Veci32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<void, void, void, AFloatV, i32V>(false),
+Case::Create<void, void, void, i32V, AFloatV>(false)
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(
+ AFloat_u32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<void, void, void, AFloat, u32>(false),
+Case::Create<void, void, void, u32, AFloat>(false)
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(
+ VecAFloat_Vecu32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<void, void, void, AFloatV, u32V>(false),
+Case::Create<void, void, void, u32V, AFloatV>(false)
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(AInt_f32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<f32, f32, f32, AInt, f32>(),
+Case::Create<f32, f32, f32, f32, AInt>()
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(VecAInt_Vecf32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<f32V, f32V, f32V, AIntV, f32V>(),
+Case::Create<f32V, f32V, f32V, f32V, AIntV>()
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(AInt_i32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<i32, i32, i32, AInt, i32>(),
+Case::Create<i32, i32, i32, i32, AInt>()
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(VecAInt_Veci32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<i32V, i32V, i32V, AIntV, i32V>(),
+Case::Create<i32V, i32V, i32V, i32V, AIntV>()
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(AInt_u32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<u32, u32, u32, AInt, u32>(),
+Case::Create<u32, u32, u32, u32, AInt>()
+ )); // clang-format on
+
+INSTANTIATE_TEST_SUITE_P(VecAInt_Vecu32,
+ IntrinsicTableAbstractBinaryTest,
+ testing::Values( // clang-format off
+// result | param lhs | param rhs | arg lhs | arg rhs
+Case::Create<u32V, u32V, u32V, AIntV, u32V>(),
+Case::Create<u32V, u32V, u32V, u32V, AIntV>()
+ )); // clang-format on
+
+} // namespace AbstractBinaryTests
+
+////////////////////////////////////////////////////////////////////////////////
+// AbstractTernaryTests
+////////////////////////////////////////////////////////////////////////////////
+namespace AbstractTernaryTests {
+
+struct Case {
+ template <typename RESULT,
+ typename PARAM_A,
+ typename PARAM_B,
+ typename PARAM_C,
+ typename ARG_A,
+ typename ARG_B,
+ typename ARG_C>
+ static Case Create(bool match = true) {
+ return {
+ match,
+ builder::DataType<RESULT>::Sem, //
+ builder::DataType<PARAM_A>::Sem, //
+ builder::DataType<PARAM_B>::Sem, //
+ builder::DataType<PARAM_C>::Sem, //
+ builder::DataType<ARG_A>::Sem, //
+ builder::DataType<ARG_B>::Sem, //
+ builder::DataType<ARG_C>::Sem, //
+ };
+ }
+ bool expected_match;
+ builder::sem_type_func_ptr expected_result;
+ builder::sem_type_func_ptr expected_param_a;
+ builder::sem_type_func_ptr expected_param_b;
+ builder::sem_type_func_ptr expected_param_c;
+ builder::sem_type_func_ptr arg_a;
+ builder::sem_type_func_ptr arg_b;
+ builder::sem_type_func_ptr arg_c;
+};
+
+struct IntrinsicTableAbstractTernaryTest : public ResolverTestWithParam<Case> {
+ std::unique_ptr<IntrinsicTable> table = IntrinsicTable::Create(*this);
+};
+
+TEST_P(IntrinsicTableAbstractTernaryTest, MatchClamp) {
+ auto* arg_a = GetParam().arg_a(*this);
+ auto* arg_b = GetParam().arg_b(*this);
+ auto* arg_c = GetParam().arg_c(*this);
+ auto* builtin =
+ table->Lookup(sem::BuiltinType::kClamp, {arg_a, arg_b, arg_c}, Source{{12, 34}});
+
+ bool matched = builtin != nullptr;
+ bool expected_match = GetParam().expected_match;
+ EXPECT_EQ(matched, expected_match) << Diagnostics().str();
+
+ auto* result = builtin ? builtin->ReturnType() : nullptr;
+ auto* expected_result = GetParam().expected_result(*this);
+ EXPECT_TYPE(result, expected_result);
+
+ auto* param_a = builtin ? builtin->Parameters()[0]->Type() : nullptr;
+ auto* expected_param_a = GetParam().expected_param_a(*this);
+ EXPECT_TYPE(param_a, expected_param_a);
+
+ auto* param_b = builtin ? builtin->Parameters()[1]->Type() : nullptr;
+ auto* expected_param_b = GetParam().expected_param_b(*this);
+ EXPECT_TYPE(param_b, expected_param_b);
+
+ auto* param_c = builtin ? builtin->Parameters()[2]->Type() : nullptr;
+ auto* expected_param_c = GetParam().expected_param_c(*this);
+ EXPECT_TYPE(param_c, expected_param_c);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ AFloat_AInt,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<f32, f32, f32, f32, AFloat, AFloat, AFloat>(),
+Case::Create<f32, f32, f32, f32, AFloat, AFloat, AInt>(),
+Case::Create<f32, f32, f32, f32, AFloat, AInt, AFloat>(),
+Case::Create<f32, f32, f32, f32, AFloat, AInt, AInt>(),
+Case::Create<f32, f32, f32, f32, AInt, AFloat, AFloat>(),
+Case::Create<f32, f32, f32, f32, AInt, AFloat, AInt>(),
+Case::Create<f32, f32, f32, f32, AInt, AInt, AFloat>(),
+Case::Create<i32, i32, i32, i32, AInt, AInt, AInt>()
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ VecAFloat_VecAInt,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<f32V, f32V, f32V, f32V, AFloatV, AFloatV, AFloatV>(),
+Case::Create<f32V, f32V, f32V, f32V, AFloatV, AFloatV, AIntV>(),
+Case::Create<f32V, f32V, f32V, f32V, AFloatV, AIntV, AFloatV>(),
+Case::Create<f32V, f32V, f32V, f32V, AFloatV, AIntV, AIntV>(),
+Case::Create<f32V, f32V, f32V, f32V, AIntV, AFloatV, AFloatV>(),
+Case::Create<f32V, f32V, f32V, f32V, AIntV, AFloatV, AIntV>(),
+Case::Create<f32V, f32V, f32V, f32V, AIntV, AIntV, AFloatV>(),
+Case::Create<i32V, i32V, i32V, i32V, AIntV, AIntV, AIntV>()
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ AFloat_f32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<f32, f32, f32, f32, AFloat, AFloat, f32>(),
+Case::Create<f32, f32, f32, f32, AFloat, f32, AFloat>(),
+Case::Create<f32, f32, f32, f32, AFloat, f32, f32>(),
+Case::Create<f32, f32, f32, f32, f32, AFloat, AFloat>(),
+Case::Create<f32, f32, f32, f32, f32, AFloat, f32>(),
+Case::Create<f32, f32, f32, f32, f32, f32, AFloat>()
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ VecAFloat_Vecf32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<f32V, f32V, f32V, f32V, AFloatV, AFloatV, f32V>(),
+Case::Create<f32V, f32V, f32V, f32V, AFloatV, f32V, AFloatV>(),
+Case::Create<f32V, f32V, f32V, f32V, AFloatV, f32V, f32V>(),
+Case::Create<f32V, f32V, f32V, f32V, f32V, AFloatV, AFloatV>(),
+Case::Create<f32V, f32V, f32V, f32V, f32V, AFloatV, f32V>(),
+Case::Create<f32V, f32V, f32V, f32V, f32V, f32V, AFloatV> ()
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ AFloat_i32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<void, void, void, void, AFloat, AFloat, i32>(false),
+Case::Create<void, void, void, void, AFloat, i32, AFloat>(false),
+Case::Create<void, void, void, void, AFloat, i32, i32>(false),
+Case::Create<void, void, void, void, i32, AFloat, AFloat>(false),
+Case::Create<void, void, void, void, i32, AFloat, i32>(false),
+Case::Create<void, void, void, void, i32, i32, AFloat>(false)
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ VecAFloat_Veci32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<void, void, void, void, AFloatV, AFloatV, i32V>(false),
+Case::Create<void, void, void, void, AFloatV, i32V, AFloatV>(false),
+Case::Create<void, void, void, void, AFloatV, i32V, i32V>(false),
+Case::Create<void, void, void, void, i32V, AFloatV, AFloatV>(false),
+Case::Create<void, void, void, void, i32V, AFloatV, i32V>(false),
+Case::Create<void, void, void, void, i32V, i32V, AFloatV>(false)
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ AFloat_u32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<void, void, void, void, AFloat, AFloat, u32>(false),
+Case::Create<void, void, void, void, AFloat, u32, AFloat>(false),
+Case::Create<void, void, void, void, AFloat, u32, u32>(false),
+Case::Create<void, void, void, void, u32, AFloat, AFloat>(false),
+Case::Create<void, void, void, void, u32, AFloat, u32>(false),
+Case::Create<void, void, void, void, u32, u32, AFloat>(false)
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ VecAFloat_Vecu32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<void, void, void, void, AFloatV, AFloatV, u32V>(false),
+Case::Create<void, void, void, void, AFloatV, u32V, AFloatV>(false),
+Case::Create<void, void, void, void, AFloatV, u32V, u32V>(false),
+Case::Create<void, void, void, void, u32V, AFloatV, AFloatV>(false),
+Case::Create<void, void, void, void, u32V, AFloatV, u32V>(false),
+Case::Create<void, void, void, void, u32V, u32V, AFloatV>(false)
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ AInt_f32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<f32, f32, f32, f32, AInt, AInt, f32>(),
+Case::Create<f32, f32, f32, f32, AInt, f32, AInt>(),
+Case::Create<f32, f32, f32, f32, AInt, f32, f32>(),
+Case::Create<f32, f32, f32, f32, f32, AInt, AInt>(),
+Case::Create<f32, f32, f32, f32, f32, AInt, f32>(),
+Case::Create<f32, f32, f32, f32, f32, f32, AInt>()
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ VecAInt_Vecf32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<f32V, f32V, f32V, f32V, AIntV, AIntV, f32V>(),
+Case::Create<f32V, f32V, f32V, f32V, AIntV, f32V, AIntV>(),
+Case::Create<f32V, f32V, f32V, f32V, AIntV, f32V, f32V>(),
+Case::Create<f32V, f32V, f32V, f32V, f32V, AIntV, AIntV>(),
+Case::Create<f32V, f32V, f32V, f32V, f32V, AIntV, f32V>(),
+Case::Create<f32V, f32V, f32V, f32V, f32V, f32V, AIntV>()
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ AInt_i32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<i32, i32, i32, i32, AInt, AInt, i32>(),
+Case::Create<i32, i32, i32, i32, AInt, i32, AInt>(),
+Case::Create<i32, i32, i32, i32, AInt, i32, i32>(),
+Case::Create<i32, i32, i32, i32, i32, AInt, AInt>(),
+Case::Create<i32, i32, i32, i32, i32, AInt, i32>(),
+Case::Create<i32, i32, i32, i32, i32, i32, AInt>()
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ VecAInt_Veci32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<i32V, i32V, i32V, i32V, AIntV, AIntV, i32V>(),
+Case::Create<i32V, i32V, i32V, i32V, AIntV, i32V, AIntV>(),
+Case::Create<i32V, i32V, i32V, i32V, AIntV, i32V, i32V>(),
+Case::Create<i32V, i32V, i32V, i32V, i32V, AIntV, AIntV>(),
+Case::Create<i32V, i32V, i32V, i32V, i32V, AIntV, i32V>(),
+Case::Create<i32V, i32V, i32V, i32V, i32V, i32V, AIntV>()
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ AInt_u32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<u32, u32, u32, u32, AInt, AInt, u32>(),
+Case::Create<u32, u32, u32, u32, AInt, u32, AInt>(),
+Case::Create<u32, u32, u32, u32, AInt, u32, u32>(),
+Case::Create<u32, u32, u32, u32, u32, AInt, AInt>(),
+Case::Create<u32, u32, u32, u32, u32, AInt, u32>(),
+Case::Create<u32, u32, u32, u32, u32, u32, AInt>()
+ // clang-format on
+ ));
+
+INSTANTIATE_TEST_SUITE_P(
+ VecAInt_Vecu32,
+ IntrinsicTableAbstractTernaryTest,
+ testing::Values( // clang-format off
+// result | param a | param b | param c | arg a | arg b | arg c
+Case::Create<u32V, u32V, u32V, u32V, AIntV, AIntV, u32V>(),
+Case::Create<u32V, u32V, u32V, u32V, AIntV, u32V, AIntV>(),
+Case::Create<u32V, u32V, u32V, u32V, AIntV, u32V, u32V>(),
+Case::Create<u32V, u32V, u32V, u32V, u32V, AIntV, AIntV>(),
+Case::Create<u32V, u32V, u32V, u32V, u32V, AIntV, u32V>(),
+Case::Create<u32V, u32V, u32V, u32V, u32V, u32V, AIntV>()
+ // clang-format on
+ ));
+
+} // namespace AbstractTernaryTests
+
} // namespace
-} // namespace tint
+} // namespace tint::resolver
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 4183b44..270acf1 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -50,6 +50,9 @@
#include "src/tint/ast/variable_decl_statement.h"
#include "src/tint/ast/vector.h"
#include "src/tint/ast/workgroup_attribute.h"
+#include "src/tint/resolver/uniformity.h"
+#include "src/tint/sem/abstract_float.h"
+#include "src/tint/sem/abstract_int.h"
#include "src/tint/sem/array.h"
#include "src/tint/sem/atomic.h"
#include "src/tint/sem/call.h"
@@ -81,12 +84,13 @@
namespace tint::resolver {
-Resolver::Resolver(ProgramBuilder* builder)
+Resolver::Resolver(ProgramBuilder* builder, bool enable_abstract_numerics)
: builder_(builder),
diagnostics_(builder->Diagnostics()),
intrinsic_table_(IntrinsicTable::Create(*builder)),
sem_(builder, dependencies_),
- validator_(builder, sem_) {}
+ validator_(builder, sem_),
+ enable_abstract_numerics_(enable_abstract_numerics) {}
Resolver::~Resolver() = default;
@@ -100,9 +104,6 @@
return false;
}
- // Create the semantic module
- builder_->Sem().SetModule(builder_->create<sem::Module>(dependencies_.ordered_globals));
-
bool result = ResolveInternal();
if (!result && !diagnostics_.contains_errors()) {
@@ -110,6 +111,10 @@
return false;
}
+ // Create the semantic module
+ builder_->Sem().SetModule(builder_->create<sem::Module>(
+ std::move(dependencies_.ordered_globals), std::move(enabled_extensions_)));
+
return result;
}
@@ -119,19 +124,16 @@
// Process all module-scope declarations in dependency order.
for (auto* decl : dependencies_.ordered_globals) {
Mark(decl);
- // Enable directives don't have sem node.
- if (decl->Is<ast::Enable>()) {
- continue;
- }
- if (!Switch(
+ if (!Switch<bool>(
decl, //
+ [&](const ast::Enable* e) { return Enable(e); },
[&](const ast::TypeDecl* td) { return TypeDecl(td); },
[&](const ast::Function* func) { return Function(func); },
[&](const ast::Variable* var) { return GlobalVariable(var); },
[&](Default) {
TINT_UNREACHABLE(Resolver, diagnostics_)
<< "unhandled global declaration: " << decl->TypeInfo().name;
- return nullptr;
+ return false;
})) {
return false;
}
@@ -145,6 +147,12 @@
return false;
}
+ if (!enabled_extensions_.contains(ast::Extension::kChromiumDisableUniformityAnalysis)) {
+ if (!AnalyzeUniformity(builder_, dependencies_)) {
+ // TODO(jrprice): Reject programs that fail uniformity analysis.
+ }
+ }
+
bool result = true;
for (auto* node : builder_->ASTNodes().Objects()) {
if (marked_.count(node) == 0) {
@@ -167,6 +175,14 @@
[&](const ast::Bool*) { return builder_->create<sem::Bool>(); },
[&](const ast::I32*) { return builder_->create<sem::I32>(); },
[&](const ast::U32*) { return builder_->create<sem::U32>(); },
+ [&](const ast::F16* t) -> sem::F16* {
+ // Validate if f16 type is allowed.
+ if (!enabled_extensions_.contains(ast::Extension::kF16)) {
+ AddError("f16 used without 'f16' extension enabled", t->source);
+ return nullptr;
+ }
+ return builder_->create<sem::F16>();
+ },
[&](const ast::F32*) { return builder_->create<sem::F32>(); },
[&](const ast::Vector* t) -> sem::Vector* {
if (!t->type) {
@@ -780,13 +796,12 @@
continue;
}
// validator_.Validate and set the default value for this dimension.
- if (is_i32 ? value.Elements()[0].i32 < 1 : value.Elements()[0].u32 < 1) {
+ if (value.Element<AInt>(0).value < 1) {
AddError("workgroup_size argument must be at least 1", values[i]->source);
return false;
}
- ws[i].value =
- is_i32 ? static_cast<uint32_t>(value.Elements()[0].i32) : value.Elements()[0].u32;
+ ws[i].value = static_cast<uint32_t>(value.Element<AInt>(0).value);
}
current_function_->SetWorkgroupSize(std::move(ws));
@@ -858,10 +873,13 @@
auto* sem =
builder_->create<sem::CaseStatement>(stmt, current_compound_statement_, current_function_);
return StatementScope(stmt, sem, [&] {
+ sem->Selectors().reserve(stmt->selectors.size());
for (auto* sel : stmt->selectors) {
- if (!Expression(sel)) {
+ auto* expr = Expression(sel);
+ if (!expr) {
return false;
}
+ sem->Selectors().emplace_back(expr);
}
Mark(stmt->body);
auto* body = BlockStatement(stmt->body);
@@ -935,17 +953,15 @@
if (stmt->continuing) {
Mark(stmt->continuing);
- if (!stmt->continuing->Empty()) {
- auto* continuing = StatementScope(
- stmt->continuing,
- builder_->create<sem::LoopContinuingBlockStatement>(
- stmt->continuing, current_compound_statement_, current_function_),
- [&] { return Statements(stmt->continuing->statements); });
- if (!continuing) {
- return false;
- }
- behaviors.Add(continuing->Behaviors());
+ auto* continuing = StatementScope(
+ stmt->continuing,
+ builder_->create<sem::LoopContinuingBlockStatement>(
+ stmt->continuing, current_compound_statement_, current_function_),
+ [&] { return Statements(stmt->continuing->statements); });
+ if (!continuing) {
+ return false;
}
+ behaviors.Add(continuing->Behaviors());
}
if (behaviors.Contains(sem::Behavior::kBreak)) { // Does the loop exit?
@@ -1014,11 +1030,19 @@
sem::Expression* Resolver::Expression(const ast::Expression* root) {
std::vector<const ast::Expression*> sorted;
- bool mark_failed = false;
+ constexpr size_t kMaxExpressionDepth = 512U;
+ bool failed = false;
if (!ast::TraverseExpressions<ast::TraverseOrder::RightToLeft>(
- root, diagnostics_, [&](const ast::Expression* expr) {
+ root, diagnostics_, [&](const ast::Expression* expr, size_t depth) {
+ if (depth > kMaxExpressionDepth) {
+ AddError(
+ "reached max expression depth of " + std::to_string(kMaxExpressionDepth),
+ expr->source);
+ failed = true;
+ return ast::TraverseAction::Stop;
+ }
if (!Mark(expr)) {
- mark_failed = true;
+ failed = true;
return ast::TraverseAction::Stop;
}
sorted.emplace_back(expr);
@@ -1027,7 +1051,7 @@
return nullptr;
}
- if (mark_failed) {
+ if (failed) {
return nullptr;
}
@@ -1137,164 +1161,211 @@
}
sem::Call* Resolver::Call(const ast::CallExpression* expr) {
+ // A CallExpression can resolve to one of:
+ // * A function call.
+ // * A builtin call.
+ // * A type constructor.
+ // * A type conversion.
+
+ // Resolve all of the arguments, their types and the set of behaviors.
std::vector<const sem::Expression*> args(expr->args.size());
- std::vector<const sem::Type*> arg_tys(args.size());
sem::Behaviors arg_behaviors;
-
- // The element type of all the arguments. Nullptr if argument types are
- // different.
- const sem::Type* arg_el_ty = nullptr;
-
for (size_t i = 0; i < expr->args.size(); i++) {
auto* arg = sem_.Get(expr->args[i]);
if (!arg) {
return nullptr;
}
args[i] = arg;
- arg_tys[i] = args[i]->Type();
arg_behaviors.Add(arg->Behaviors());
-
- // Determine the common argument element type
- auto* el_ty = arg_tys[i]->UnwrapRef();
- if (auto* vec = el_ty->As<sem::Vector>()) {
- el_ty = vec->type();
- } else if (auto* mat = el_ty->As<sem::Matrix>()) {
- el_ty = mat->type();
- }
- if (i == 0) {
- arg_el_ty = el_ty;
- } else if (arg_el_ty != el_ty) {
- arg_el_ty = nullptr;
- }
}
-
arg_behaviors.Remove(sem::Behavior::kNext);
- auto type_ctor_or_conv = [&](const sem::Type* ty) -> sem::Call* {
- // The call has resolved to a type constructor or cast.
- if (args.size() == 1) {
- auto* target = ty;
- auto* source = args[0]->Type()->UnwrapRef();
- if ((source != target) && //
- ((source->is_scalar() && target->is_scalar()) ||
- (source->Is<sem::Vector>() && target->Is<sem::Vector>()) ||
- (source->Is<sem::Matrix>() && target->Is<sem::Matrix>()))) {
- // Note: Matrix types currently cannot be converted (the element type
- // must only be f32). We implement this for the day we support other
- // matrix element types.
- return TypeConversion(expr, ty, args[0], arg_tys[0]);
- }
+ // Did any arguments have side effects?
+ bool has_side_effects =
+ std::any_of(args.begin(), args.end(), [](auto* e) { return e->HasSideEffects(); });
+
+ // ct_ctor_or_conv is a helper for building either a sem::TypeConstructor or sem::TypeConversion
+ // call for a CtorConvIntrinsic with an optional template argument type.
+ auto ct_ctor_or_conv = [&](CtorConvIntrinsic ty, const sem::Type* template_arg) -> sem::Call* {
+ auto arg_tys = utils::Transform(args, [](auto* arg) { return arg->Type(); });
+ auto* call_target = intrinsic_table_->Lookup(ty, template_arg, arg_tys, expr->source);
+ if (!call_target) {
+ return nullptr;
}
- return TypeConstructor(expr, ty, std::move(args), std::move(arg_tys));
+ auto value = EvaluateConstantValue(expr, call_target->ReturnType());
+ return builder_->create<sem::Call>(expr, call_target, std::move(args), current_statement_,
+ value, has_side_effects);
};
- // Resolve the target of the CallExpression to determine whether this is a
- // function call, cast or type constructor expression.
- if (expr->target.type) {
- const sem::Type* ty = nullptr;
-
- auto err_cannot_infer_el_ty = [&](std::string name) {
- AddError("cannot infer " + name +
- " element type, as constructor arguments have different types",
- expr->source);
- for (size_t i = 0; i < args.size(); i++) {
- auto* arg = args[i];
- AddNote("argument " + std::to_string(i) + " has type " +
- arg->Type()->FriendlyName(builder_->Symbols()),
- arg->Declaration()->source);
- }
- };
-
- if (!expr->args.empty()) {
- // vecN() without explicit element type?
- // Try to infer element type from args
- if (auto* vec = expr->target.type->As<ast::Vector>()) {
- if (!vec->type) {
- if (!arg_el_ty) {
- err_cannot_infer_el_ty("vector");
- return nullptr;
- }
-
- Mark(vec);
- auto* v =
- builder_->create<sem::Vector>(arg_el_ty, static_cast<uint32_t>(vec->width));
- if (!validator_.Vector(v, vec->source)) {
- return nullptr;
- }
- builder_->Sem().Add(vec, v);
- ty = v;
- }
- }
-
- // matNxM() without explicit element type?
- // Try to infer element type from args
- if (auto* mat = expr->target.type->As<ast::Matrix>()) {
- if (!mat->type) {
- if (!arg_el_ty) {
- err_cannot_infer_el_ty("matrix");
- return nullptr;
- }
-
- Mark(mat);
- auto* column_type = builder_->create<sem::Vector>(arg_el_ty, mat->rows);
- auto* m = builder_->create<sem::Matrix>(column_type, mat->columns);
- if (!validator_.Matrix(m, mat->source)) {
- return nullptr;
- }
- builder_->Sem().Add(mat, m);
- ty = m;
- }
- }
- }
-
- if (ty == nullptr) {
- ty = Type(expr->target.type);
- if (!ty) {
+ // ct_ctor_or_conv is a helper for building either a sem::TypeConstructor or sem::TypeConversion
+ // call for the given semantic type.
+ auto ty_ctor_or_conv = [&](const sem::Type* ty) {
+ return Switch(
+ ty, //
+ [&](const sem::Vector* v) {
+ return ct_ctor_or_conv(VectorCtorConvIntrinsic(v->Width()), v->type());
+ },
+ [&](const sem::Matrix* m) {
+ return ct_ctor_or_conv(MatrixCtorConvIntrinsic(m->columns(), m->rows()), m->type());
+ },
+ [&](const sem::I32*) { return ct_ctor_or_conv(CtorConvIntrinsic::kI32, nullptr); },
+ [&](const sem::U32*) { return ct_ctor_or_conv(CtorConvIntrinsic::kU32, 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* {
+ auto* call_target = utils::GetOrCreate(
+ array_ctors_, ArrayConstructorSig{{arr, args.size()}},
+ [&]() -> sem::TypeConstructor* {
+ sem::ParameterList params(args.size());
+ for (size_t i = 0; i < args.size(); i++) {
+ params[i] = builder_->create<sem::Parameter>(
+ nullptr, // declaration
+ static_cast<uint32_t>(i), // index
+ arr->ElemType(), // type
+ ast::StorageClass::kNone, // storage_class
+ ast::Access::kUndefined); // access
+ }
+ return builder_->create<sem::TypeConstructor>(arr, std::move(params));
+ });
+ auto value = EvaluateConstantValue(expr, call_target->ReturnType());
+ return builder_->create<sem::Call>(expr, call_target, std::move(args),
+ current_statement_, value, has_side_effects);
+ },
+ [&](const sem::Struct* str) -> sem::Call* {
+ auto* call_target = utils::GetOrCreate(
+ struct_ctors_, StructConstructorSig{{str, args.size()}},
+ [&]() -> sem::TypeConstructor* {
+ sem::ParameterList params(std::min(args.size(), str->Members().size()));
+ for (size_t i = 0, n = params.size(); i < n; i++) {
+ params[i] = builder_->create<sem::Parameter>(
+ nullptr, // declaration
+ static_cast<uint32_t>(i), // index
+ str->Members()[i]->Type(), // type
+ ast::StorageClass::kNone, // storage_class
+ ast::Access::kUndefined); // access
+ }
+ return builder_->create<sem::TypeConstructor>(str, std::move(params));
+ });
+ auto value = EvaluateConstantValue(expr, call_target->ReturnType());
+ return builder_->create<sem::Call>(expr, call_target, std::move(args),
+ current_statement_, value, has_side_effects);
+ },
+ [&](Default) {
+ AddError("type is not constructible", expr->source);
return nullptr;
- }
- }
+ });
+ };
- return type_ctor_or_conv(ty);
+ // ast::CallExpression has a target which is either an ast::Type or an ast::IdentifierExpression
+ sem::Call* call = nullptr;
+ if (expr->target.type) {
+ // ast::CallExpression has an ast::Type as the target.
+ // This call is either a type constructor or type conversion.
+ call = Switch(
+ expr->target.type,
+ [&](const ast::Vector* v) -> sem::Call* {
+ Mark(v);
+ // vector element type must be inferred if it was not specified.
+ sem::Type* template_arg = nullptr;
+ if (v->type) {
+ template_arg = Type(v->type);
+ if (!template_arg) {
+ return nullptr;
+ }
+ }
+ if (auto* c = ct_ctor_or_conv(VectorCtorConvIntrinsic(v->width), template_arg)) {
+ builder_->Sem().Add(expr->target.type, c->Target()->ReturnType());
+ return c;
+ }
+ return nullptr;
+ },
+ [&](const ast::Matrix* m) -> sem::Call* {
+ Mark(m);
+ // matrix element type must be inferred if it was not specified.
+ sem::Type* template_arg = nullptr;
+ if (m->type) {
+ template_arg = Type(m->type);
+ if (!template_arg) {
+ return nullptr;
+ }
+ }
+ if (auto* c = ct_ctor_or_conv(MatrixCtorConvIntrinsic(m->columns, m->rows),
+ template_arg)) {
+ builder_->Sem().Add(expr->target.type, c->Target()->ReturnType());
+ return c;
+ }
+ return nullptr;
+ },
+ [&](const ast::Type* ast) -> sem::Call* {
+ // Handler for AST types that do not have an optional element type.
+ if (auto* ty = Type(ast)) {
+ return ty_ctor_or_conv(ty);
+ }
+ return nullptr;
+ },
+ [&](Default) {
+ TINT_ICE(Resolver, diagnostics_)
+ << expr->source << " unhandled CallExpression target:\n"
+ << "type: "
+ << (expr->target.type ? expr->target.type->TypeInfo().name : "<null>");
+ return nullptr;
+ });
+ } else {
+ // ast::CallExpression has an ast::IdentifierExpression as the target.
+ // This call is either a function call, builtin call, type constructor or type conversion.
+ auto* ident = expr->target.name;
+ Mark(ident);
+ auto* resolved = sem_.ResolvedSymbol(ident);
+ call = Switch<sem::Call*>(
+ resolved, //
+ [&](sem::Type* ty) {
+ // A type constructor or conversions.
+ // Note: Unlike the code path where we're resolving the call target from an
+ // ast::Type, all types must already have the element type explicitly specified, so
+ // there's no need to infer element types.
+ return ty_ctor_or_conv(ty);
+ },
+ [&](sem::Function* func) {
+ return FunctionCall(expr, func, std::move(args), arg_behaviors);
+ },
+ [&](sem::Variable* var) {
+ auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
+ AddError("cannot call variable '" + name + "'", ident->source);
+ AddNote("'" + name + "' declared here", var->Declaration()->source);
+ return nullptr;
+ },
+ [&](Default) -> sem::Call* {
+ auto name = builder_->Symbols().NameFor(ident->symbol);
+ auto builtin_type = sem::ParseBuiltinType(name);
+ if (builtin_type != sem::BuiltinType::kNone) {
+ return BuiltinCall(expr, builtin_type, std::move(args));
+ }
+
+ TINT_ICE(Resolver, diagnostics_)
+ << expr->source << " unhandled CallExpression target:\n"
+ << "resolved: " << (resolved ? resolved->TypeInfo().name : "<null>") << "\n"
+ << "name: " << builder_->Symbols().NameFor(ident->symbol);
+ return nullptr;
+ });
}
- auto* ident = expr->target.name;
- Mark(ident);
+ if (!call) {
+ return nullptr;
+ }
- auto* resolved = sem_.ResolvedSymbol(ident);
- return Switch(
- resolved, //
- [&](sem::Type* type) { return type_ctor_or_conv(type); },
- [&](sem::Function* func) {
- return FunctionCall(expr, func, std::move(args), arg_behaviors);
- },
- [&](sem::Variable* var) {
- auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
- AddError("cannot call variable '" + name + "'", ident->source);
- AddNote("'" + name + "' declared here", var->Declaration()->source);
- return nullptr;
- },
- [&](Default) -> sem::Call* {
- auto name = builder_->Symbols().NameFor(ident->symbol);
- auto builtin_type = sem::ParseBuiltinType(name);
- if (builtin_type != sem::BuiltinType::kNone) {
- return BuiltinCall(expr, builtin_type, std::move(args), std::move(arg_tys));
- }
-
- TINT_ICE(Resolver, diagnostics_)
- << expr->source << " unresolved CallExpression target:\n"
- << "resolved: " << (resolved ? resolved->TypeInfo().name : "<null>") << "\n"
- << "name: " << builder_->Symbols().NameFor(ident->symbol);
- return nullptr;
- });
+ return validator_.Call(call, current_statement_) ? call : nullptr;
}
sem::Call* Resolver::BuiltinCall(const ast::CallExpression* expr,
sem::BuiltinType builtin_type,
- const std::vector<const sem::Expression*> args,
- const std::vector<const sem::Type*> arg_tys) {
- auto* builtin = intrinsic_table_->Lookup(builtin_type, std::move(arg_tys), expr->source);
- if (!builtin) {
- return nullptr;
+ std::vector<const sem::Expression*> args) {
+ const sem::Builtin* builtin = nullptr;
+ {
+ auto arg_tys = utils::Transform(args, [](auto* arg) { return arg->Type(); });
+ builtin = intrinsic_table_->Lookup(builtin_type, arg_tys, expr->source);
+ if (!builtin) {
+ return nullptr;
+ }
}
if (builtin->IsDeprecated()) {
@@ -1309,7 +1380,7 @@
current_function_->AddDirectlyCalledBuiltin(builtin);
- if (!validator_.RequiredExtensionForBuiltinFunction(call, builder_->AST().Extensions())) {
+ if (!validator_.RequiredExtensionForBuiltinFunction(call, enabled_extensions_)) {
return nullptr;
}
@@ -1317,21 +1388,7 @@
if (!validator_.TextureBuiltinFunction(call)) {
return nullptr;
}
- // Collect a texture/sampler pair for this builtin.
- const auto& signature = builtin->Signature();
- int texture_index = signature.IndexOf(sem::ParameterUsage::kTexture);
- if (texture_index == -1) {
- TINT_ICE(Resolver, diagnostics_) << "texture builtin without texture parameter";
- }
-
- auto* texture = args[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;
- current_function_->AddTextureSamplerPair(texture, sampler);
- }
+ CollectTextureSamplerPairs(builtin, call->Arguments());
}
if (!validator_.BuiltinCall(call)) {
@@ -1343,9 +1400,27 @@
return call;
}
+void Resolver::CollectTextureSamplerPairs(const sem::Builtin* builtin,
+ const std::vector<const sem::Expression*>& args) const {
+ // Collect a texture/sampler pair for this builtin.
+ const auto& signature = builtin->Signature();
+ int texture_index = signature.IndexOf(sem::ParameterUsage::kTexture);
+ if (texture_index == -1) {
+ TINT_ICE(Resolver, diagnostics_) << "texture builtin without texture parameter";
+ }
+ auto* texture = args[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;
+ current_function_->AddTextureSamplerPair(texture, sampler);
+ }
+}
+
sem::Call* Resolver::FunctionCall(const ast::CallExpression* expr,
sem::Function* target,
- const std::vector<const sem::Expression*> args,
+ std::vector<const sem::Expression*> args,
sem::Behaviors arg_behaviors) {
auto sym = expr->target.name->symbol;
auto name = builder_->Symbols().NameFor(sym);
@@ -1371,25 +1446,7 @@
current_function_->AddTransitivelyReferencedGlobal(var);
}
- // Map all texture/sampler pairs from the target function to the
- // current function. These can only be global or parameter
- // variables. Resolve any parameter variables to the corresponding
- // argument passed to the current function. Leave global variables
- // as-is. Then add the mapped pair to the current function's list of
- // texture/sampler pairs.
- for (sem::VariablePair pair : target->TextureSamplerPairs()) {
- const sem::Variable* texture = pair.first;
- const sem::Variable* sampler = pair.second;
- if (auto* param = texture->As<sem::Parameter>()) {
- texture = args[param->Index()]->As<sem::VariableUser>()->Variable();
- }
- if (sampler) {
- if (auto* param = sampler->As<sem::Parameter>()) {
- sampler = args[param->Index()]->As<sem::VariableUser>()->Variable();
- }
- }
- current_function_->AddTextureSamplerPair(texture, sampler);
- }
+ CollectTextureSamplerPairs(target, call->Arguments());
}
target->AddCallSite(call);
@@ -1403,131 +1460,27 @@
return call;
}
-sem::Call* Resolver::TypeConversion(const ast::CallExpression* expr,
- const sem::Type* target,
- const sem::Expression* arg,
- const sem::Type* source) {
- // It is not valid to have a type-cast call expression inside a call
- // statement.
- if (IsCallStatement(expr)) {
- AddError("type cast evaluated but not used", expr->source);
- return nullptr;
- }
-
- auto* call_target = utils::GetOrCreate(
- type_conversions_, TypeConversionSig{target, source}, [&]() -> sem::TypeConversion* {
- // Now that the argument types have been determined, make sure that
- // they obey the conversion rules laid out in
- // https://gpuweb.github.io/gpuweb/wgsl/#conversion-expr.
- bool ok = Switch(
- target,
- [&](const sem::Vector* vec_type) {
- return validator_.VectorConstructorOrCast(expr, vec_type);
- },
- [&](const sem::Matrix* mat_type) {
- // Note: Matrix types currently cannot be converted (the element
- // type must only be f32). We implement this for the day we
- // support other matrix element types.
- return validator_.MatrixConstructorOrCast(expr, mat_type);
- },
- [&](const sem::Array* arr_type) {
- return validator_.ArrayConstructorOrCast(expr, arr_type);
- },
- [&](const sem::Struct* struct_type) {
- return validator_.StructureConstructorOrCast(expr, struct_type);
- },
- [&](Default) {
- if (target->is_scalar()) {
- return validator_.ScalarConstructorOrCast(expr, target);
- }
- AddError("type is not constructible", expr->source);
- return false;
- });
- if (!ok) {
- return nullptr;
+void Resolver::CollectTextureSamplerPairs(sem::Function* func,
+ const std::vector<const sem::Expression*>& args) const {
+ // Map all texture/sampler pairs from the target function to the
+ // current function. These can only be global or parameter
+ // variables. Resolve any parameter variables to the corresponding
+ // argument passed to the current function. Leave global variables
+ // as-is. Then add the mapped pair to the current function's list of
+ // texture/sampler pairs.
+ for (sem::VariablePair pair : func->TextureSamplerPairs()) {
+ const sem::Variable* texture = pair.first;
+ const sem::Variable* sampler = pair.second;
+ if (auto* param = texture->As<sem::Parameter>()) {
+ texture = args[param->Index()]->As<sem::VariableUser>()->Variable();
+ }
+ if (sampler) {
+ if (auto* param = sampler->As<sem::Parameter>()) {
+ sampler = args[param->Index()]->As<sem::VariableUser>()->Variable();
}
-
- auto* param =
- builder_->create<sem::Parameter>(nullptr, // declaration
- 0, // index
- source->UnwrapRef(), // type
- ast::StorageClass::kNone, // storage_class
- ast::Access::kUndefined); // access
- return builder_->create<sem::TypeConversion>(target, param);
- });
-
- if (!call_target) {
- return nullptr;
+ }
+ current_function_->AddTextureSamplerPair(texture, sampler);
}
-
- auto val = EvaluateConstantValue(expr, target);
- bool has_side_effects = arg->HasSideEffects();
- return builder_->create<sem::Call>(expr, call_target, std::vector<const sem::Expression*>{arg},
- current_statement_, val, has_side_effects);
-}
-
-sem::Call* Resolver::TypeConstructor(const ast::CallExpression* expr,
- const sem::Type* ty,
- const std::vector<const sem::Expression*> args,
- const std::vector<const sem::Type*> arg_tys) {
- // It is not valid to have a type-constructor call expression as a call
- // statement.
- if (IsCallStatement(expr)) {
- AddError("type constructor evaluated but not used", expr->source);
- return nullptr;
- }
-
- auto* call_target = utils::GetOrCreate(
- type_ctors_, TypeConstructorSig{ty, arg_tys}, [&]() -> sem::TypeConstructor* {
- // Now that the argument types have been determined, make sure that
- // they obey the constructor type rules laid out in
- // https://gpuweb.github.io/gpuweb/wgsl/#type-constructor-expr.
- bool ok = Switch(
- ty,
- [&](const sem::Vector* vec_type) {
- return validator_.VectorConstructorOrCast(expr, vec_type);
- },
- [&](const sem::Matrix* mat_type) {
- return validator_.MatrixConstructorOrCast(expr, mat_type);
- },
- [&](const sem::Array* arr_type) {
- return validator_.ArrayConstructorOrCast(expr, arr_type);
- },
- [&](const sem::Struct* struct_type) {
- return validator_.StructureConstructorOrCast(expr, struct_type);
- },
- [&](Default) {
- if (ty->is_scalar()) {
- return validator_.ScalarConstructorOrCast(expr, ty);
- }
- AddError("type is not constructible", expr->source);
- return false;
- });
- if (!ok) {
- return nullptr;
- }
-
- return builder_->create<sem::TypeConstructor>(
- ty, utils::Transform(arg_tys,
- [&](const sem::Type* t, size_t i) -> const sem::Parameter* {
- return builder_->create<sem::Parameter>(
- nullptr, // declaration
- static_cast<uint32_t>(i), // index
- t->UnwrapRef(), // type
- ast::StorageClass::kNone, // storage_class
- ast::Access::kUndefined); // access
- }));
- });
-
- if (!call_target) {
- return nullptr;
- }
-
- auto val = EvaluateConstantValue(expr, ty);
- bool has_side_effects =
- std::any_of(args.begin(), args.end(), [](auto* e) { return e->HasSideEffects(); });
- return builder_->create<sem::Call>(expr, call_target, std::move(args), current_statement_, val,
- has_side_effects);
}
sem::Expression* Resolver::Literal(const ast::LiteralExpression* literal) {
@@ -1536,8 +1489,10 @@
[&](const ast::IntLiteralExpression* i) -> sem::Type* {
switch (i->suffix) {
case ast::IntLiteralExpression::Suffix::kNone:
- // TODO(crbug.com/tint/1504): This will need to become abstract-int.
- // For now, treat as 'i32'.
+ if (enable_abstract_numerics_) {
+ return builder_->create<sem::AbstractInt>();
+ }
+ return builder_->create<sem::I32>();
case ast::IntLiteralExpression::Suffix::kI:
return builder_->create<sem::I32>();
case ast::IntLiteralExpression::Suffix::kU:
@@ -1545,7 +1500,13 @@
}
return nullptr;
},
- [&](const ast::FloatLiteralExpression*) { return builder_->create<sem::F32>(); },
+ [&](const ast::FloatLiteralExpression* f) -> sem::Type* {
+ if (f->suffix == ast::FloatLiteralExpression::Suffix::kNone &&
+ enable_abstract_numerics_) {
+ return builder_->create<sem::AbstractFloat>();
+ }
+ return builder_->create<sem::F32>();
+ },
[&](const ast::BoolLiteralExpression*) { return builder_->create<sem::Bool>(); },
[&](Default) { return nullptr; });
@@ -1745,27 +1706,27 @@
}
sem::Expression* Resolver::Binary(const ast::BinaryExpression* expr) {
- auto* lhs = sem_.Get(expr->lhs);
- auto* rhs = sem_.Get(expr->rhs);
+ const auto* lhs = sem_.Get(expr->lhs);
+ const auto* rhs = sem_.Get(expr->rhs);
auto* lhs_ty = lhs->Type()->UnwrapRef();
auto* rhs_ty = rhs->Type()->UnwrapRef();
- auto* ty = intrinsic_table_->Lookup(expr->op, lhs_ty, rhs_ty, expr->source, false).result;
- if (!ty) {
+ auto op = intrinsic_table_->Lookup(expr->op, lhs_ty, rhs_ty, expr->source, false);
+ if (!op.result) {
return nullptr;
}
- auto val = EvaluateConstantValue(expr, ty);
+ auto val = EvaluateConstantValue(expr, op.result);
bool has_side_effects = lhs->HasSideEffects() || rhs->HasSideEffects();
- auto* sem =
- builder_->create<sem::Expression>(expr, ty, current_statement_, val, has_side_effects);
+ auto* sem = builder_->create<sem::Expression>(expr, op.result, current_statement_, val,
+ has_side_effects);
sem->Behaviors() = lhs->Behaviors() + rhs->Behaviors();
return sem;
}
sem::Expression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
- auto* expr = sem_.Get(unary->expr);
+ const auto* expr = sem_.Get(unary->expr);
auto* expr_ty = expr->Type();
if (!expr_ty) {
return nullptr;
@@ -1818,6 +1779,7 @@
if (!ty) {
return nullptr;
}
+ break;
}
}
@@ -1828,6 +1790,11 @@
return sem;
}
+bool Resolver::Enable(const ast::Enable* enable) {
+ enabled_extensions_.add(enable->extension);
+ return true;
+}
+
sem::Type* Resolver::TypeDecl(const ast::TypeDecl* named_type) {
sem::Type* result = nullptr;
if (auto* alias = named_type->As<ast::Alias>()) {
@@ -1932,13 +1899,12 @@
return nullptr;
}
- if (ty->is_signed_integer_scalar() ? count_val.Elements()[0].i32 < 1
- : count_val.Elements()[0].u32 < 1u) {
+ if (count_val.Element<AInt>(0).value < 1) {
AddError("array size must be at least 1", size_source);
return nullptr;
}
- count = count_val.Elements()[0].u32;
+ count = static_cast<uint32_t>(count_val.Element<AInt>(0).value);
}
auto size = std::max<uint64_t>(count, 1) * stride;
@@ -2150,19 +2116,21 @@
auto& behaviors = current_statement_->Behaviors();
behaviors = sem::Behavior::kReturn;
+ const sem::Type* value_ty = nullptr;
if (auto* value = stmt->value) {
auto* expr = Expression(value);
if (!expr) {
return false;
}
behaviors.Add(expr->Behaviors() - sem::Behavior::kNext);
+ value_ty = expr->Type()->UnwrapRef();
+ } else {
+ value_ty = builder_->create<sem::Void>();
}
// Validate after processing the return value expression so that its type
// is available for validation.
- auto* ret_type =
- stmt->value ? sem_.TypeOf(stmt->value)->UnwrapRef() : builder_->create<sem::Void>();
- return validator_.Return(stmt, current_function_->ReturnType(), ret_type,
+ return validator_.Return(stmt, current_function_->ReturnType(), value_ty,
current_statement_);
});
}
@@ -2186,6 +2154,7 @@
return false;
}
behaviors.Add(c->Behaviors());
+ sem->Cases().emplace_back(c);
}
if (behaviors.Contains(sem::Behavior::kBreak)) {
@@ -2453,36 +2422,4 @@
return sem::ParseBuiltinType(name) != sem::BuiltinType::kNone;
}
-bool Resolver::IsCallStatement(const ast::Expression* expr) const {
- return current_statement_ &&
- Is<ast::CallStatement>(current_statement_->Declaration(),
- [&](auto* stmt) { return stmt->expr == expr; });
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Resolver::TypeConversionSig
-////////////////////////////////////////////////////////////////////////////////
-bool Resolver::TypeConversionSig::operator==(const TypeConversionSig& rhs) const {
- return target == rhs.target && source == rhs.source;
-}
-std::size_t Resolver::TypeConversionSig::Hasher::operator()(const TypeConversionSig& sig) const {
- return utils::Hash(sig.target, sig.source);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Resolver::TypeConstructorSig
-////////////////////////////////////////////////////////////////////////////////
-Resolver::TypeConstructorSig::TypeConstructorSig(const sem::Type* ty,
- const std::vector<const sem::Type*> params)
- : type(ty), parameters(params) {}
-Resolver::TypeConstructorSig::TypeConstructorSig(const TypeConstructorSig&) = default;
-Resolver::TypeConstructorSig::~TypeConstructorSig() = default;
-
-bool Resolver::TypeConstructorSig::operator==(const TypeConstructorSig& rhs) const {
- return type == rhs.type && parameters == rhs.parameters;
-}
-std::size_t Resolver::TypeConstructorSig::Hasher::operator()(const TypeConstructorSig& sig) const {
- return utils::Hash(sig.type, sig.parameters);
-}
-
} // namespace tint::resolver
diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h
index 4b75dc0..1725072 100644
--- a/src/tint/resolver/resolver.h
+++ b/src/tint/resolver/resolver.h
@@ -17,6 +17,7 @@
#include <memory>
#include <string>
+#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
@@ -74,7 +75,10 @@
public:
/// Constructor
/// @param builder the program builder
- explicit Resolver(ProgramBuilder* builder);
+ /// @param enable_abstract_numerics if true, then treat unsuffixed integers as abstract integers
+ /// and unsuffixed floats as abstract floats. This is a temporary flag while abstract numerics
+ /// are being developed. Once complete, this will be permanently enabled.
+ explicit Resolver(ProgramBuilder* builder, bool enable_abstract_numerics = false);
/// Destructor
~Resolver();
@@ -184,23 +188,14 @@
sem::Function* Function(const ast::Function*);
sem::Call* FunctionCall(const ast::CallExpression*,
sem::Function* target,
- const std::vector<const sem::Expression*> args,
+ std::vector<const sem::Expression*> args,
sem::Behaviors arg_behaviors);
sem::Expression* Identifier(const ast::IdentifierExpression*);
sem::Call* BuiltinCall(const ast::CallExpression*,
sem::BuiltinType,
- const std::vector<const sem::Expression*> args,
- const std::vector<const sem::Type*> arg_tys);
+ std::vector<const sem::Expression*> args);
sem::Expression* Literal(const ast::LiteralExpression*);
sem::Expression* MemberAccessor(const ast::MemberAccessorExpression*);
- sem::Call* TypeConversion(const ast::CallExpression* expr,
- const sem::Type* ty,
- const sem::Expression* arg,
- const sem::Type* arg_ty);
- sem::Call* TypeConstructor(const ast::CallExpression* expr,
- const sem::Type* ty,
- const std::vector<const sem::Expression*> args,
- const std::vector<const sem::Type*> arg_tys);
sem::Expression* UnaryOp(const ast::UnaryOpExpression*);
// Statement resolving methods
@@ -226,6 +221,12 @@
sem::Statement* VariableDeclStatement(const ast::VariableDeclStatement*);
bool Statements(const ast::StatementList&);
+ // CollectTextureSamplerPairs() collects all the texture/sampler pairs from the target function
+ // / builtin, and records these on the current function by calling AddTextureSamplerPair().
+ void CollectTextureSamplerPairs(sem::Function* func,
+ const std::vector<const sem::Expression*>& args) const;
+ void CollectTextureSamplerPairs(const sem::Builtin* builtin,
+ const std::vector<const sem::Expression*>& args) const;
/// Resolves the WorkgroupSize for the given function, assigning it to
/// current_function_
@@ -237,6 +238,10 @@
/// @param ty the ast::Type
sem::Type* Type(const ast::Type* ty);
+ /// @param enable the enable declaration
+ /// @returns the resolved extension
+ bool Enable(const ast::Enable* enable);
+
/// @param named_type the named type to resolve
/// @returns the resolved semantic type
sem::Type* TypeDecl(const ast::TypeDecl* named_type);
@@ -327,7 +332,9 @@
//////////////////////////////////////////////////////////////////////////////
/// Cast `Value` to `target_type`
/// @return the casted value
- sem::Constant ConstantCast(const sem::Constant& value, const sem::Type* target_elem_type);
+ sem::Constant ConstantCast(const sem::Constant& value,
+ const sem::Type* target_type,
+ const sem::Type* target_element_type = nullptr);
sem::Constant EvaluateConstantValue(const ast::Expression* expr, const sem::Type* type);
sem::Constant EvaluateConstantValue(const ast::LiteralExpression* literal,
@@ -337,39 +344,13 @@
/// @returns true if the symbol is the name of a builtin function.
bool IsBuiltin(Symbol) const;
- /// @returns true if `expr` is the current CallStatement's CallExpression
- bool IsCallStatement(const ast::Expression* expr) const;
+ // ArrayConstructorSig represents a unique array constructor signature.
+ // It is a tuple of the array type and number of arguments provided.
+ using ArrayConstructorSig = utils::UnorderedKeyWrapper<std::tuple<const sem::Array*, size_t>>;
- struct TypeConversionSig {
- const sem::Type* target;
- const sem::Type* source;
-
- bool operator==(const TypeConversionSig&) const;
-
- /// Hasher provides a hash function for the TypeConversionSig
- struct Hasher {
- /// @param sig the TypeConversionSig to create a hash for
- /// @return the hash value
- std::size_t operator()(const TypeConversionSig& sig) const;
- };
- };
-
- struct TypeConstructorSig {
- const sem::Type* type;
- const std::vector<const sem::Type*> parameters;
-
- TypeConstructorSig(const sem::Type* ty, const std::vector<const sem::Type*> params);
- TypeConstructorSig(const TypeConstructorSig&);
- ~TypeConstructorSig();
- bool operator==(const TypeConstructorSig&) const;
-
- /// Hasher provides a hash function for the TypeConstructorSig
- struct Hasher {
- /// @param sig the TypeConstructorSig to create a hash for
- /// @return the hash value
- std::size_t operator()(const TypeConstructorSig& sig) const;
- };
- };
+ // StructConstructorSig represents a unique structure constructor signature.
+ // It is a tuple of the structure type and number of arguments provided.
+ using StructConstructorSig = utils::UnorderedKeyWrapper<std::tuple<const sem::Struct*, size_t>>;
ProgramBuilder* const builder_;
diag::List& diagnostics_;
@@ -377,19 +358,20 @@
DependencyGraph dependencies_;
SemHelper sem_;
Validator validator_;
+ ast::Extensions enabled_extensions_;
std::vector<sem::Function*> entry_points_;
std::unordered_map<const sem::Type*, const Source&> atomic_composite_info_;
std::unordered_set<const ast::Node*> marked_;
std::unordered_map<uint32_t, const sem::Variable*> constant_ids_;
- std::unordered_map<TypeConversionSig, sem::CallTarget*, TypeConversionSig::Hasher>
- type_conversions_;
- std::unordered_map<TypeConstructorSig, sem::CallTarget*, TypeConstructorSig::Hasher>
- type_ctors_;
+ std::unordered_map<ArrayConstructorSig, sem::CallTarget*> array_ctors_;
+ std::unordered_map<StructConstructorSig, sem::CallTarget*> struct_ctors_;
sem::Function* current_function_ = nullptr;
sem::Statement* current_statement_ = nullptr;
sem::CompoundStatement* current_compound_statement_ = nullptr;
sem::BlockStatement* current_block_ = nullptr;
+
+ bool enable_abstract_numerics_ = false;
};
} // namespace tint::resolver
diff --git a/src/tint/resolver/resolver_behavior_test.cc b/src/tint/resolver/resolver_behavior_test.cc
index 9cb26dc..3a3b14f 100644
--- a/src/tint/resolver/resolver_behavior_test.cc
+++ b/src/tint/resolver/resolver_behavior_test.cc
@@ -19,6 +19,7 @@
#include "src/tint/sem/expression.h"
#include "src/tint/sem/for_loop_statement.h"
#include "src/tint/sem/if_statement.h"
+#include "src/tint/sem/switch_statement.h"
using namespace tint::number_suffixes; // NOLINT
diff --git a/src/tint/resolver/resolver_constants.cc b/src/tint/resolver/resolver_constants.cc
index 2a8a1d1..265b06d 100644
--- a/src/tint/resolver/resolver_constants.cc
+++ b/src/tint/resolver/resolver_constants.cc
@@ -14,6 +14,8 @@
#include "src/tint/resolver/resolver.h"
+#include "src/tint/sem/abstract_float.h"
+#include "src/tint/sem/abstract_int.h"
#include "src/tint/sem/constant.h"
#include "src/tint/sem/type_constructor.h"
#include "src/tint/utils/map.h"
@@ -21,6 +23,33 @@
using namespace tint::number_suffixes; // NOLINT
namespace tint::resolver {
+namespace {
+
+sem::Constant::Scalars CastScalars(sem::Constant::Scalars in, const sem::Type* target_type) {
+ sem::Constant::Scalars out;
+ out.reserve(in.size());
+ for (auto v : in) {
+ // TODO(crbug.com/tint/1504): Check that value fits in new type
+ out.emplace_back(Switch<sem::Constant::Scalar>(
+ target_type, //
+ [&](const sem::AbstractInt*) { return sem::Constant::Cast<AInt>(v); },
+ [&](const sem::AbstractFloat*) { return sem::Constant::Cast<AFloat>(v); },
+ [&](const sem::I32*) { return sem::Constant::Cast<AInt>(v); },
+ [&](const sem::U32*) { return sem::Constant::Cast<AInt>(v); },
+ [&](const sem::F32*) { return sem::Constant::Cast<AFloat>(v); },
+ [&](const sem::F16*) { return sem::Constant::Cast<AFloat>(v); },
+ [&](const sem::Bool*) { return sem::Constant::Cast<bool>(v); },
+ [&](Default) {
+ diag::List diags;
+ TINT_UNREACHABLE(Semantic, diags)
+ << "invalid element type " << target_type->TypeInfo().name;
+ return sem::Constant::Scalar(false);
+ }));
+ }
+ return out;
+}
+
+} // namespace
sem::Constant Resolver::EvaluateConstantValue(const ast::Expression* expr, const sem::Type* type) {
if (auto* e = expr->As<ast::LiteralExpression>()) {
@@ -37,13 +66,10 @@
return Switch(
literal,
[&](const ast::IntLiteralExpression* lit) {
- if (lit->suffix == ast::IntLiteralExpression::Suffix::kU) {
- return sem::Constant{type, {u32(lit->value)}};
- }
- return sem::Constant{type, {i32(lit->value)}};
+ return sem::Constant{type, {AInt(lit->value)}};
},
[&](const ast::FloatLiteralExpression* lit) {
- return sem::Constant{type, {f32(lit->value)}};
+ return sem::Constant{type, {AFloat(lit->value)}};
},
[&](const ast::BoolLiteralExpression* lit) {
return sem::Constant{type, {lit->value}};
@@ -52,96 +78,80 @@
sem::Constant Resolver::EvaluateConstantValue(const ast::CallExpression* call,
const sem::Type* type) {
- auto* vec = type->As<sem::Vector>();
-
- // For now, only fold scalars and vectors
- if (!type->is_scalar() && !vec) {
+ uint32_t result_size = 0;
+ auto* el_ty = sem::Type::ElementOf(type, &result_size);
+ if (!el_ty) {
return {};
}
- auto* elem_type = vec ? vec->type() : type;
- int result_size = vec ? static_cast<int>(vec->Width()) : 1;
+ // ElementOf() will also return the element type of array, which we do not support.
+ if (type->Is<sem::Array>()) {
+ return {};
+ }
// For zero value init, return 0s
if (call->args.empty()) {
- if (elem_type->Is<sem::I32>()) {
- return sem::Constant(type, sem::Constant::Scalars(result_size, 0_i));
- }
- if (elem_type->Is<sem::U32>()) {
- return sem::Constant(type, sem::Constant::Scalars(result_size, 0_u));
- }
- if (elem_type->Is<sem::F32>()) {
- return sem::Constant(type, sem::Constant::Scalars(result_size, 0_f));
- }
- if (elem_type->Is<sem::Bool>()) {
- return sem::Constant(type, sem::Constant::Scalars(result_size, false));
- }
+ using Scalars = sem::Constant::Scalars;
+ return Switch(
+ el_ty,
+ [&](const sem::AbstractInt*) {
+ return sem::Constant(type, Scalars(result_size, AInt(0)));
+ },
+ [&](const sem::AbstractFloat*) {
+ return sem::Constant(type, Scalars(result_size, AFloat(0)));
+ },
+ [&](const sem::I32*) { return sem::Constant(type, Scalars(result_size, AInt(0))); },
+ [&](const sem::U32*) { return sem::Constant(type, Scalars(result_size, AInt(0))); },
+ [&](const sem::F32*) { return sem::Constant(type, Scalars(result_size, AFloat(0))); },
+ [&](const sem::F16*) { return sem::Constant(type, Scalars(result_size, AFloat(0))); },
+ [&](const sem::Bool*) { return sem::Constant(type, Scalars(result_size, false)); });
}
- // Build value for type_ctor from each child value by casting to
- // type_ctor's type.
+ // Build value for type_ctor from each child value by casting to type_ctor's type.
sem::Constant::Scalars elems;
for (auto* expr : call->args) {
auto* arg = builder_->Sem().Get(expr);
- if (!arg || !arg->ConstantValue()) {
+ if (!arg) {
return {};
}
- auto cast = ConstantCast(arg->ConstantValue(), elem_type);
- elems.insert(elems.end(), cast.Elements().begin(), cast.Elements().end());
+ auto value = arg->ConstantValue();
+ if (!value) {
+ return {};
+ }
+ elems.insert(elems.end(), value.Elements().begin(), value.Elements().end());
}
// Splat single-value initializers
if (elems.size() == 1) {
- for (int i = 0; i < result_size - 1; ++i) {
+ for (uint32_t i = 0; i < result_size - 1; ++i) {
elems.emplace_back(elems[0]);
}
}
- return sem::Constant(type, std::move(elems));
+ // Finally cast the elements to the desired type.
+ auto cast = CastScalars(elems, el_ty);
+
+ return sem::Constant(type, std::move(cast));
}
sem::Constant Resolver::ConstantCast(const sem::Constant& value,
- const sem::Type* target_elem_type) {
- if (value.ElementType() == target_elem_type) {
+ const sem::Type* target_type,
+ const sem::Type* target_element_type /* = nullptr */) {
+ if (value.Type() == target_type) {
return value;
}
- sem::Constant::Scalars elems;
- for (size_t i = 0; i < value.Elements().size(); ++i) {
- elems.emplace_back(Switch<sem::Constant::Scalar>(
- target_elem_type,
- [&](const sem::I32*) {
- return value.WithScalarAt(i, [](auto&& s) { //
- return i32(static_cast<int32_t>(s));
- });
- },
- [&](const sem::U32*) {
- return value.WithScalarAt(i, [](auto&& s) { //
- return u32(static_cast<uint32_t>(s));
- });
- },
- [&](const sem::F32*) {
- return value.WithScalarAt(i, [](auto&& s) { //
- return static_cast<f32>(s);
- });
- },
- [&](const sem::Bool*) {
- return value.WithScalarAt(i, [](auto&& s) { //
- return static_cast<bool>(s);
- });
- },
- [&](Default) {
- diag::List diags;
- TINT_UNREACHABLE(Semantic, diags)
- << "invalid element type " << target_elem_type->TypeInfo().name;
- return sem::Constant::Scalar(false);
- }));
+ if (target_element_type == nullptr) {
+ target_element_type = sem::Type::ElementOf(target_type);
+ }
+ if (target_element_type == nullptr) {
+ return {};
+ }
+ if (value.ElementType() == target_element_type) {
+ return sem::Constant(target_type, value.Elements());
}
- auto* target_type =
- value.Type()->Is<sem::Vector>()
- ? builder_->create<sem::Vector>(target_elem_type, static_cast<uint32_t>(elems.size()))
- : target_elem_type;
+ auto elems = CastScalars(value.Elements(), target_element_type);
return sem::Constant(target_type, elems);
}
diff --git a/src/tint/resolver/resolver_constants_test.cc b/src/tint/resolver/resolver_constants_test.cc
index a9624ca..05e6e4c 100644
--- a/src/tint/resolver/resolver_constants_test.cc
+++ b/src/tint/resolver/resolver_constants_test.cc
@@ -39,7 +39,7 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 1u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].i32, 99);
+ EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 99);
}
TEST_F(ResolverConstantsTest, Scalar_u32) {
@@ -54,7 +54,7 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 1u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].u32, 99u);
+ EXPECT_EQ(sem->ConstantValue().Element<AInt>(0).value, 99u);
}
TEST_F(ResolverConstantsTest, Scalar_f32) {
@@ -69,7 +69,7 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 1u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].f32, 9.9f);
+ EXPECT_EQ(sem->ConstantValue().Element<AFloat>(0).value, 9.9f);
}
TEST_F(ResolverConstantsTest, Scalar_bool) {
@@ -84,7 +84,7 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 1u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].bool_, true);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(0), true);
}
TEST_F(ResolverConstantsTest, Vec3_ZeroInit_i32) {
@@ -101,9 +101,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].i32, 0);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].i32, 0);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].i32, 0);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_ZeroInit_u32) {
@@ -120,9 +120,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::U32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].u32, 0u);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].u32, 0u);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].u32, 0u);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_ZeroInit_f32) {
@@ -139,9 +139,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].f32, 0.0f);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].f32, 0.0f);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].f32, 0.0f);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_ZeroInit_bool) {
@@ -158,9 +158,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::Bool>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].bool_, false);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].bool_, false);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].bool_, false);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(0), false);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(1), false);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(2), false);
}
TEST_F(ResolverConstantsTest, Vec3_Splat_i32) {
@@ -177,9 +177,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].i32, 99);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].i32, 99);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].i32, 99);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_Splat_u32) {
@@ -196,9 +196,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::U32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].u32, 99u);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].u32, 99u);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].u32, 99u);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_Splat_f32) {
@@ -215,9 +215,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].f32, 9.9f);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].f32, 9.9f);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].f32, 9.9f);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_Splat_bool) {
@@ -234,9 +234,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::Bool>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].bool_, true);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].bool_, true);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].bool_, true);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(0), true);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(1), true);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(2), true);
}
TEST_F(ResolverConstantsTest, Vec3_FullConstruct_i32) {
@@ -253,9 +253,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].i32, 1);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].i32, 2);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].i32, 3);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_FullConstruct_u32) {
@@ -272,9 +272,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::U32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].u32, 1u);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].u32, 2u);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].u32, 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);
}
TEST_F(ResolverConstantsTest, Vec3_FullConstruct_f32) {
@@ -291,9 +291,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].f32, 1.f);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].f32, 2.f);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].f32, 3.f);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_FullConstruct_bool) {
@@ -310,9 +310,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::Bool>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].bool_, true);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].bool_, false);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].bool_, true);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(0), true);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(1), false);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(2), true);
}
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_i32) {
@@ -329,9 +329,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].i32, 1);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].i32, 2);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].i32, 3);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_u32) {
@@ -348,9 +348,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::U32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].u32, 1u);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].u32, 2u);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].u32, 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);
}
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f32) {
@@ -367,9 +367,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].f32, 1.f);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].f32, 2.f);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].f32, 3.f);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_bool) {
@@ -386,9 +386,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::Bool>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].bool_, true);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].bool_, false);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].bool_, true);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(0), true);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(1), false);
+ EXPECT_EQ(sem->ConstantValue().Element<bool>(2), true);
}
TEST_F(ResolverConstantsTest, Vec3_Cast_f32_to_32) {
@@ -405,9 +405,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].i32, 1);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].i32, 2);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].i32, 3);
+ 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);
}
TEST_F(ResolverConstantsTest, Vec3_Cast_u32_to_f32) {
@@ -424,9 +424,9 @@
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
ASSERT_EQ(sem->ConstantValue().Elements().size(), 3u);
- EXPECT_EQ(sem->ConstantValue().Elements()[0].f32, 10.f);
- EXPECT_EQ(sem->ConstantValue().Elements()[1].f32, 20.f);
- EXPECT_EQ(sem->ConstantValue().Elements()[2].f32, 30.f);
+ 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);
}
} // namespace
diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc
index 3b86a48..07c661c 100644
--- a/src/tint/resolver/resolver_test.cc
+++ b/src/tint/resolver/resolver_test.cc
@@ -42,6 +42,7 @@
#include "src/tint/sem/reference.h"
#include "src/tint/sem/sampled_texture.h"
#include "src/tint/sem/statement.h"
+#include "src/tint/sem/switch_statement.h"
#include "src/tint/sem/variable.h"
using ::testing::ElementsAre;
@@ -111,11 +112,11 @@
auto* assign = Assign(lhs, rhs);
auto* block = Block(assign);
- ast::CaseSelectorList lit;
- lit.push_back(Expr(3_i));
- auto* cse = create<ast::CaseStatement>(lit, block);
+ auto* sel = Expr(3_i);
+ auto* cse = Case(sel, block);
+ auto* def = DefaultCase();
auto* cond_var = Var("c", ty.i32());
- auto* sw = Switch(cond_var, cse, DefaultCase());
+ auto* sw = Switch(cond_var, cse, def);
WrapInFunction(v, cond_var, sw);
EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -127,6 +128,13 @@
EXPECT_EQ(StmtOf(lhs), assign);
EXPECT_EQ(StmtOf(rhs), assign);
EXPECT_EQ(BlockOf(assign), block);
+ auto* sem = Sem().Get(sw);
+ ASSERT_EQ(sem->Cases().size(), 2u);
+ EXPECT_EQ(sem->Cases()[0]->Declaration(), cse);
+ ASSERT_EQ(sem->Cases()[0]->Selectors().size(), 1u);
+ EXPECT_EQ(sem->Cases()[0]->Selectors()[0]->Declaration(), sel);
+ EXPECT_EQ(sem->Cases()[1]->Declaration(), def);
+ EXPECT_EQ(sem->Cases()[1]->Selectors().size(), 0u);
}
TEST_F(ResolverTest, Stmt_Block) {
@@ -2098,5 +2106,33 @@
ElementsAre(f0, v0, a0, s0, f1, v1, a1, s1, f2, v2, a2, s2));
}
+constexpr size_t kMaxExpressionDepth = 512U;
+
+TEST_F(ResolverTest, MaxExpressionDepth_Pass) {
+ auto* b = Var("b", ty.i32());
+ const ast::Expression* chain = nullptr;
+ for (size_t i = 0; i < kMaxExpressionDepth; ++i) {
+ chain = Add(chain ? chain : Expr("b"), Expr("b"));
+ }
+ auto* a = Let("a", nullptr, chain);
+ WrapInFunction(b, a);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverTest, MaxExpressionDepth_Fail) {
+ auto* b = Var("b", ty.i32());
+ const ast::Expression* chain = nullptr;
+ for (size_t i = 0; i < kMaxExpressionDepth + 1; ++i) {
+ chain = Add(chain ? chain : Expr("b"), Expr("b"));
+ }
+ auto* a = Let("a", nullptr, chain);
+ WrapInFunction(b, a);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_THAT(r()->error(), HasSubstr("error: reached max expression depth of " +
+ std::to_string(kMaxExpressionDepth)));
+}
+
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/resolver/resolver_test_helper.cc b/src/tint/resolver/resolver_test_helper.cc
index dd590d9..75a6698 100644
--- a/src/tint/resolver/resolver_test_helper.cc
+++ b/src/tint/resolver/resolver_test_helper.cc
@@ -18,7 +18,8 @@
namespace tint::resolver {
-TestHelper::TestHelper() : resolver_(std::make_unique<Resolver>(this)) {}
+TestHelper::TestHelper()
+ : resolver_(std::make_unique<Resolver>(this, /* enable_abstract_numerics */ true)) {}
TestHelper::~TestHelper() = default;
diff --git a/src/tint/resolver/resolver_test_helper.h b/src/tint/resolver/resolver_test_helper.h
index d54e57c..6c5a74f 100644
--- a/src/tint/resolver/resolver_test_helper.h
+++ b/src/tint/resolver/resolver_test_helper.h
@@ -22,6 +22,8 @@
#include "gtest/gtest.h"
#include "src/tint/program_builder.h"
#include "src/tint/resolver/resolver.h"
+#include "src/tint/sem/abstract_float.h"
+#include "src/tint/sem/abstract_int.h"
#include "src/tint/sem/expression.h"
#include "src/tint/sem/statement.h"
#include "src/tint/sem/variable.h"
@@ -174,6 +176,15 @@
template <typename T>
struct DataType {};
+/// Helper that represents no-type. Returns nullptr for all static methods.
+template <>
+struct DataType<void> {
+ /// @return nullptr
+ static inline const ast::Type* AST(ProgramBuilder&) { return nullptr; }
+ /// @return nullptr
+ static inline const sem::Type* Sem(ProgramBuilder&) { return nullptr; }
+};
+
/// Helper for building bool types and expressions
template <>
struct DataType<bool> {
@@ -192,6 +203,8 @@
static inline const ast::Expression* Expr(ProgramBuilder& b, int elem_value) {
return b.Expr(elem_value == 0);
}
+ /// @returns the WGSL name for the type
+ static inline std::string Name() { return "bool"; }
};
/// Helper for building i32 types and expressions
@@ -212,6 +225,8 @@
static inline const ast::Expression* Expr(ProgramBuilder& b, int elem_value) {
return b.Expr(static_cast<i32>(elem_value));
}
+ /// @returns the WGSL name for the type
+ static inline std::string Name() { return "i32"; }
};
/// Helper for building u32 types and expressions
@@ -232,6 +247,8 @@
static inline const ast::Expression* Expr(ProgramBuilder& b, int elem_value) {
return b.Expr(static_cast<u32>(elem_value));
}
+ /// @returns the WGSL name for the type
+ static inline std::string Name() { return "u32"; }
};
/// Helper for building f32 types and expressions
@@ -252,6 +269,72 @@
static inline const ast::Expression* Expr(ProgramBuilder& b, int elem_value) {
return b.Expr(static_cast<f32>(elem_value));
}
+ /// @returns the WGSL name for the type
+ static inline std::string Name() { return "f32"; }
+};
+
+/// Helper for building f16 types and expressions
+template <>
+struct DataType<f16> {
+ /// false as f16 is not a composite type
+ static constexpr bool is_composite = false;
+
+ /// @param b the ProgramBuilder
+ /// @return a new AST f16 type
+ static inline const ast::Type* AST(ProgramBuilder& b) { return b.ty.f16(); }
+ /// @param b the ProgramBuilder
+ /// @return the semantic f16 type
+ static inline const sem::Type* Sem(ProgramBuilder& b) { return b.create<sem::F16>(); }
+ /// @param b the ProgramBuilder
+ /// @param elem_value the value f16 will be initialized with
+ /// @return a new AST f16 literal value expression
+ static inline const ast::Expression* Expr(ProgramBuilder& b, int elem_value) {
+ return b.Expr(static_cast<f16>(elem_value));
+ }
+ /// @returns the WGSL name for the type
+ static inline std::string Name() { return "f16"; }
+};
+
+/// Helper for building abstract float types and expressions
+template <>
+struct DataType<AFloat> {
+ /// false as AFloat is not a composite type
+ static constexpr bool is_composite = false;
+
+ /// @returns nullptr, as abstract floats are un-typeable
+ static inline const ast::Type* AST(ProgramBuilder&) { return nullptr; }
+ /// @param b the ProgramBuilder
+ /// @return the semantic abstract-float type
+ static inline const sem::Type* Sem(ProgramBuilder& b) { return b.create<sem::AbstractFloat>(); }
+ /// @param b the ProgramBuilder
+ /// @param elem_value the value the abstract-float literal will be constructed with
+ /// @return a new AST abstract-float literal value expression
+ static inline const ast::Expression* Expr(ProgramBuilder& b, int elem_value) {
+ return b.Expr(AFloat(elem_value));
+ }
+ /// @returns the WGSL name for the type
+ static inline std::string Name() { return "abstract-float"; }
+};
+
+/// Helper for building abstract integer types and expressions
+template <>
+struct DataType<AInt> {
+ /// false as AFloat is not a composite type
+ static constexpr bool is_composite = false;
+
+ /// @returns nullptr, as abstract integers are un-typeable
+ static inline const ast::Type* AST(ProgramBuilder&) { return nullptr; }
+ /// @param b the ProgramBuilder
+ /// @return the semantic abstract-int type
+ static inline const sem::Type* Sem(ProgramBuilder& b) { return b.create<sem::AbstractInt>(); }
+ /// @param b the ProgramBuilder
+ /// @param elem_value the value the abstract-int literal will be constructed with
+ /// @return a new AST abstract-int literal value expression
+ static inline const ast::Expression* Expr(ProgramBuilder& b, int elem_value) {
+ return b.Expr(AInt(elem_value));
+ }
+ /// @returns the WGSL name for the type
+ static inline std::string Name() { return "abstract-int"; }
};
/// Helper for building vector types and expressions
@@ -288,6 +371,10 @@
}
return args;
}
+ /// @returns the WGSL name for the type
+ static inline std::string Name() {
+ return "vec" + std::to_string(N) + "<" + DataType<T>::Name() + ">";
+ }
};
/// Helper for building matrix types and expressions
@@ -325,6 +412,11 @@
}
return args;
}
+ /// @returns the WGSL name for the type
+ static inline std::string Name() {
+ return "mat" + std::to_string(N) + "x" + std::to_string(M) + "<" + DataType<T>::Name() +
+ ">";
+ }
};
/// Helper for building alias types and expressions
@@ -366,6 +458,8 @@
// Construct
return b.Construct(AST(b), DataType<T>::ExprArgs(b, elem_value));
}
+ /// @returns the WGSL name for the type
+ static inline std::string Name() { return "alias_" + std::to_string(ID); }
};
/// Helper for building pointer types and expressions
@@ -394,6 +488,8 @@
b.Global(sym, DataType<T>::AST(b), ast::StorageClass::kPrivate);
return b.AddressOf(sym);
}
+ /// @returns the WGSL name for the type
+ static inline std::string Name() { return "ptr<" + DataType<T>::Name() + ">"; }
};
/// Helper for building array types and expressions
@@ -437,6 +533,10 @@
}
return args;
}
+ /// @returns the WGSL name for the type
+ static inline std::string Name() {
+ return "array<" + DataType<T>::Name() + ", " + std::to_string(N) + ">";
+ }
};
/// Struct of all creation pointer types
diff --git a/src/tint/resolver/type_constructor_validation_test.cc b/src/tint/resolver/type_constructor_validation_test.cc
index 4c37ee5..3277ee8 100644
--- a/src/tint/resolver/type_constructor_validation_test.cc
+++ b/src/tint/resolver/type_constructor_validation_test.cc
@@ -57,7 +57,7 @@
}
TEST_F(ResolverTypeConstructorValidationTest, InferTypeTest_Simple) {
- // var a = 1;
+ // var a = 1i;
// var b = a;
auto* a = Var("a", nullptr, ast::StorageClass::kNone, Expr(1_i));
auto* b = Var("b", nullptr, ast::StorageClass::kNone, Expr("a"));
@@ -147,15 +147,16 @@
<< "expected: " << FriendlyName(expected) << "\n";
}
static constexpr Params from_arithmetic_expression_cases[] = {
- ParamsFor<i32>(), ParamsFor<u32>(), ParamsFor<f32>(),
- ParamsFor<vec3<f32>>(), ParamsFor<mat3x3<f32>>(),
-
- // TODO(amaiorano): Uncomment once https://crbug.com/tint/680 is fixed
- // ParamsFor<alias<ty_i32>>(),
- // ParamsFor<alias<ty_u32>>(),
- // ParamsFor<alias<ty_f32>>(),
- // ParamsFor<alias<ty_vec3<f32>>>(),
- // ParamsFor<alias<ty_mat3x3<f32>>>(),
+ ParamsFor<i32>(),
+ ParamsFor<u32>(),
+ ParamsFor<f32>(),
+ ParamsFor<vec3<f32>>(),
+ ParamsFor<mat3x3<f32>>(),
+ ParamsFor<alias<i32>>(),
+ ParamsFor<alias<u32>>(),
+ ParamsFor<alias<f32>>(),
+ ParamsFor<alias<vec3<f32>>>(),
+ ParamsFor<alias<mat3x3<f32>>>(),
};
INSTANTIATE_TEST_SUITE_P(ResolverTypeConstructorValidationTest,
InferTypeTest_FromArithmeticExpression,
@@ -234,15 +235,18 @@
}
static constexpr Params valid_cases[] = {
- // Direct init (non-conversions)
- ParamsFor<bool, bool>(Kind::Construct), //
- ParamsFor<i32, i32>(Kind::Construct), //
- ParamsFor<u32, u32>(Kind::Construct), //
- ParamsFor<f32, f32>(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), //
+ // Identity
+ ParamsFor<bool, bool>(Kind::Construct), //
+ ParamsFor<i32, i32>(Kind::Construct), //
+ ParamsFor<u32, u32>(Kind::Construct), //
+ ParamsFor<f32, f32>(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<mat3x3<f32>, mat3x3<f32>>(Kind::Construct), //
+ ParamsFor<mat2x3<f32>, mat2x3<f32>>(Kind::Construct), //
+ ParamsFor<mat3x2<f32>, mat3x2<f32>>(Kind::Construct), //
// Splat
ParamsFor<vec3<bool>, bool>(Kind::Construct), //
@@ -250,6 +254,10 @@
ParamsFor<vec3<u32>, u32>(Kind::Construct), //
ParamsFor<vec3<f32>, f32>(Kind::Construct), //
+ ParamsFor<mat3x3<f32>, f32>(Kind::Construct), //
+ ParamsFor<mat2x3<f32>, f32>(Kind::Construct), //
+ ParamsFor<mat3x2<f32>, f32>(Kind::Construct), //
+
// Conversion
ParamsFor<bool, u32>(Kind::Conversion), //
ParamsFor<bool, i32>(Kind::Conversion), //
@@ -310,7 +318,7 @@
ASSERT_TRUE(r()->Resolve()) << r()->error();
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
switch (params.kind) {
case Kind::Construct: {
@@ -408,7 +416,7 @@
WrapInFunction(a);
ASSERT_FALSE(r()->Resolve());
- ASSERT_EQ(r()->error(), "12:34 error: expected zero or one value in constructor, got 2");
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for f32(f32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, ConversionConstructorInvalid_InvalidInitializer) {
@@ -417,9 +425,8 @@
WrapInFunction(a);
ASSERT_FALSE(r()->Resolve());
- ASSERT_EQ(r()->error(),
- "12:34 error: cannot construct 'f32' with a value of type "
- "'array<f32, 4>'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for f32(array<f32, 4>)"));
}
} // namespace ConversionConstructTest
@@ -433,7 +440,7 @@
ASSERT_TRUE(r()->Resolve()) << r()->error();
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::TypeConstructor>();
@@ -449,7 +456,7 @@
ASSERT_TRUE(r()->Resolve()) << r()->error();
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
EXPECT_TRUE(call->Type()->Is<sem::Array>());
auto* ctor = call->Target()->As<sem::TypeConstructor>();
@@ -622,7 +629,7 @@
ASSERT_NE(TypeOf(expr), nullptr);
ASSERT_TRUE(TypeOf(expr)->Is<sem::I32>());
- auto* call = Sem().Get(expr);
+ auto* call = Sem().Get<sem::Call>(expr);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -640,7 +647,7 @@
ASSERT_NE(TypeOf(expr), nullptr);
ASSERT_TRUE(TypeOf(expr)->Is<sem::U32>());
- auto* call = Sem().Get(expr);
+ auto* call = Sem().Get<sem::Call>(expr);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -658,7 +665,7 @@
ASSERT_NE(TypeOf(expr), nullptr);
ASSERT_TRUE(TypeOf(expr)->Is<sem::F32>());
- auto* call = Sem().Get(expr);
+ auto* call = Sem().Get<sem::Call>(expr);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -676,7 +683,7 @@
ASSERT_NE(TypeOf(expr), nullptr);
ASSERT_TRUE(TypeOf(expr)->Is<sem::I32>());
- auto* call = Sem().Get(expr);
+ auto* call = Sem().Get<sem::Call>(expr);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConversion>();
ASSERT_NE(ctor, nullptr);
@@ -694,7 +701,7 @@
ASSERT_NE(TypeOf(expr), nullptr);
ASSERT_TRUE(TypeOf(expr)->Is<sem::U32>());
- auto* call = Sem().Get(expr);
+ auto* call = Sem().Get<sem::Call>(expr);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConversion>();
ASSERT_NE(ctor, nullptr);
@@ -712,7 +719,7 @@
ASSERT_NE(TypeOf(expr), nullptr);
ASSERT_TRUE(TypeOf(expr)->Is<sem::F32>());
- auto* call = Sem().Get(expr);
+ auto* call = Sem().Get<sem::Call>(expr);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConversion>();
ASSERT_NE(ctor, nullptr);
@@ -727,101 +734,90 @@
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec2F32_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec2<f32>(Expr(Source{{12, 34}}, 1_i), 1_f);
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<f32>(), 1_i, 2_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'f32', found 'i32'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<f32>(i32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec2U32_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec2<u32>(1_u, Expr(Source{{12, 34}}, 1_i));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<u32>(), 1_u, 2_i));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'u32', found 'i32'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<u32>(u32, i32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec2I32_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec2<i32>(Expr(Source{{12, 34}}, 1_u), 1_i);
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<i32>(), 1_u, 2_i));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'i32', found 'u32'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<i32>(u32, i32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec2Bool_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec2<bool>(true, Expr(Source{{12, 34}}, 1_i));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<bool>(), true, 1_i));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'bool', found 'i32'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<bool>(bool, i32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec2_Error_Vec3ArgumentCardinalityTooLarge) {
- auto* tc = vec2<f32>(Construct(Source{{12, 34}}, ty.vec3<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<f32>(), vec3<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec2<f32>' with 3 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<f32>(vec3<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec2_Error_Vec4ArgumentCardinalityTooLarge) {
- auto* tc = vec2<f32>(Construct(Source{{12, 34}}, ty.vec4<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<f32>(), vec4<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec2<f32>' with 4 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<f32>(vec4<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2_Error_TooManyArgumentsScalar) {
- auto* tc = vec2<f32>(Expr(Source{{12, 34}}, 1_f), Expr(Source{{12, 40}}, 1_f),
- Expr(Source{{12, 46}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<f32>(), 1_f, 2_f, 3_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec2<f32>' with 3 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<f32>(f32, f32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2_Error_TooManyArgumentsVector) {
- auto* tc = vec2<f32>(Construct(Source{{12, 34}}, ty.vec2<f32>()),
- Construct(Source{{12, 40}}, ty.vec2<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<f32>(), vec2<f32>(), vec2<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec2<f32>' with 4 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<f32>(vec2<f32>, vec2<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec2_Error_TooManyArgumentsVectorAndScalar) {
- auto* tc = vec2<f32>(Construct(Source{{12, 34}}, ty.vec2<f32>()), Expr(Source{{12, 40}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<f32>(), vec2<f32>(), 1_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec2<f32>' with 3 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<f32>(vec2<f32>, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2_Error_InvalidArgumentType) {
- auto* tc = vec2<f32>(Construct(Source{{12, 34}}, ty.mat2x2<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec2<f32>(), mat2x2<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: expected vector or scalar type in vector "
- "constructor; found: mat2x2<f32>");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<f32>(mat2x2<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2_Success_ZeroValue) {
@@ -835,7 +831,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 2u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -854,7 +850,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 2u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -875,7 +871,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 2u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -896,7 +892,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 2u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -917,7 +913,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 2u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -938,7 +934,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 2u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -958,7 +954,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 2u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConversion>();
ASSERT_NE(ctor, nullptr);
@@ -969,117 +965,107 @@
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec3F32_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec3<f32>(1_f, 1_f, Expr(Source{{12, 34}}, 1_i));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<f32>(), 1_f, 2_f, 3_i));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'f32', found 'i32'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f32>(f32, f32, i32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec3U32_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec3<u32>(1_u, Expr(Source{{12, 34}}, 1_i), 1_u);
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<u32>(), 1_u, 2_i, 3_u));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'u32', found 'i32'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<u32>(u32, i32, u32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec3I32_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec3<i32>(1_i, Expr(Source{{12, 34}}, 1_u), 1_i);
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<i32>(), 1_i, 2_u, 3_i));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'i32', found 'u32'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<i32>(i32, u32, i32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec3Bool_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec3<bool>(true, Expr(Source{{12, 34}}, 1_i), false);
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<bool>(), false, 1_i, true));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'bool', found 'i32'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<bool>(bool, i32, bool)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec3_Error_Vec4ArgumentCardinalityTooLarge) {
- auto* tc = vec3<f32>(Construct(Source{{12, 34}}, ty.vec4<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<f32>(), vec4<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f32>(vec4<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Error_TooFewArgumentsScalar) {
- auto* tc = vec3<f32>(Expr(Source{{12, 34}}, 1_f), Expr(Source{{12, 40}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<f32>(), 1_f, 2_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec3<f32>' with 2 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f32>(f32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Error_TooManyArgumentsScalar) {
- auto* tc = vec3<f32>(Expr(Source{{12, 34}}, 1_f), Expr(Source{{12, 40}}, 1_f),
- Expr(Source{{12, 46}}, 1_f), Expr(Source{{12, 52}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<f32>(), 1_f, 2_f, 3_f, 4_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f32>(f32, f32, f32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Error_TooFewArgumentsVec2) {
- auto* tc = vec3<f32>(Construct(Source{{12, 34}}, ty.vec2<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<f32>(), vec2<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec3<f32>' with 2 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f32>(vec2<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Error_TooManyArgumentsVec2) {
- auto* tc = vec3<f32>(Construct(Source{{12, 34}}, ty.vec2<f32>()),
- Construct(Source{{12, 40}}, ty.vec2<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<f32>(), vec2<f32>(), vec2<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f32>(vec2<f32>, vec2<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec3_Error_TooManyArgumentsVec2AndScalar) {
- auto* tc = vec3<f32>(Construct(Source{{12, 34}}, ty.vec2<f32>()), Expr(Source{{12, 40}}, 1_f),
- Expr(Source{{12, 46}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<f32>(), vec2<f32>(), 1_f, 1_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f32>(vec2<f32>, f32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Error_TooManyArgumentsVec3) {
- auto* tc = vec3<f32>(Construct(Source{{12, 34}}, ty.vec3<f32>()), Expr(Source{{12, 40}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<f32>(), vec3<f32>(), 1_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f32>(vec3<f32>, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Error_InvalidArgumentType) {
- auto* tc = vec3<f32>(Construct(Source{{12, 34}}, ty.mat2x2<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<f32>(), mat2x2<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: expected vector or scalar type in vector "
- "constructor; found: mat2x2<f32>");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f32>(mat2x2<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Success_ZeroValue) {
@@ -1093,7 +1079,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 3u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -1112,7 +1098,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 3u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -1134,7 +1120,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 3u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -1156,7 +1142,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 3u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -1178,7 +1164,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 3u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -1200,7 +1186,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 3u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -1221,7 +1207,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 3u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -1242,7 +1228,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 3u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConstructor>();
ASSERT_NE(ctor, nullptr);
@@ -1262,7 +1248,7 @@
EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->Width(), 3u);
- auto* call = Sem().Get(tc);
+ auto* call = Sem().Get<sem::Call>(tc);
ASSERT_NE(call, nullptr);
auto* ctor = call->Target()->As<sem::TypeConversion>();
ASSERT_NE(ctor, nullptr);
@@ -1273,163 +1259,156 @@
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4F32_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec4<f32>(1_f, 1_f, Expr(Source{{12, 34}}, 1_i), 1_f);
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), 1_f, 1_f, 1_i, 1_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'f32', found 'i32'");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(f32, f32, i32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4U32_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec4<u32>(1_u, 1_u, Expr(Source{{12, 34}}, 1_i), 1_u);
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<u32>(), 1_u, 1_u, 1_i, 1_u));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'u32', found 'i32'");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<u32>(u32, u32, i32, u32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4I32_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec4<i32>(1_i, 1_i, Expr(Source{{12, 34}}, 1_u), 1_i);
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<i32>(), 1_i, 1_i, 1_u, 1_i));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'i32', found 'u32'");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<i32>(i32, i32, u32, i32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4Bool_Error_ScalarArgumentTypeMismatch) {
- auto* tc = vec4<bool>(true, false, Expr(Source{{12, 34}}, 1_i), true);
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<bool>(), true, false, 1_i, true));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'bool', found 'i32'");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<bool>(bool, bool, i32, bool)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec4_Error_TooFewArgumentsScalar) {
- auto* tc = vec4<f32>(Expr(Source{{12, 34}}, 1_f), Expr(Source{{12, 40}}, 1_f),
- Expr(Source{{12, 46}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), 1_f, 2_f, 3_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 3 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(f32, f32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec4_Error_TooManyArgumentsScalar) {
- auto* tc = vec4<f32>(Expr(Source{{12, 34}}, 1_f), Expr(Source{{12, 40}}, 1_f),
- Expr(Source{{12, 46}}, 1_f), Expr(Source{{12, 52}}, 1_f),
- Expr(Source{{12, 58}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), 1_f, 2_f, 3_f, 4_f, 5_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(f32, f32, f32, f32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4_Error_TooFewArgumentsVec2AndScalar) {
- auto* tc = vec4<f32>(Construct(Source{{12, 34}}, ty.vec2<f32>()), Expr(Source{{12, 40}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), vec2<f32>(), 1_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 3 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(vec2<f32>, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4_Error_TooManyArgumentsVec2AndScalars) {
- auto* tc = vec4<f32>(Construct(Source{{12, 34}}, ty.vec2<f32>()), Expr(Source{{12, 40}}, 1_f),
- Expr(Source{{12, 46}}, 1_f), Expr(Source{{12, 52}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), vec2<f32>(), 1_f, 2_f, 3_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(vec2<f32>, f32, f32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4_Error_TooManyArgumentsVec2Vec2Scalar) {
- auto* tc = vec4<f32>(Construct(Source{{12, 34}}, ty.vec2<f32>()),
- Construct(Source{{12, 40}}, ty.vec2<f32>()), Expr(Source{{12, 46}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), vec2<f32>(), vec2<f32>(), 1_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(vec2<f32>, vec2<f32>, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4_Error_TooManyArgumentsVec2Vec2Vec2) {
- auto* tc = vec4<f32>(Construct(Source{{12, 34}}, ty.vec2<f32>()),
- Construct(Source{{12, 40}}, ty.vec2<f32>()),
- Construct(Source{{12, 40}}, ty.vec2<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(
+ Construct(Source{{12, 34}}, ty.vec4<f32>(), vec2<f32>(), vec2<f32>(), vec2<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 6 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr(
+ "12:34 error: no matching constructor for vec4<f32>(vec2<f32>, vec2<f32>, vec2<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec4_Error_TooFewArgumentsVec3) {
- auto* tc = vec4<f32>(Construct(Source{{12, 34}}, ty.vec3<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), vec3<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 3 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(vec3<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4_Error_TooManyArgumentsVec3AndScalars) {
- auto* tc = vec4<f32>(Construct(Source{{12, 34}}, ty.vec3<f32>()), Expr(Source{{12, 40}}, 1_f),
- Expr(Source{{12, 46}}, 1_f));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), vec3<f32>(), 1_f, 2_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(vec3<f32>, f32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4_Error_TooManyArgumentsVec3AndVec2) {
- auto* tc = vec4<f32>(Construct(Source{{12, 34}}, ty.vec3<f32>()),
- Construct(Source{{12, 40}}, ty.vec2<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), vec3<f32>(), vec2<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(vec3<f32>, vec2<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4_Error_TooManyArgumentsVec2AndVec3) {
- auto* tc = vec4<f32>(Construct(Source{{12, 34}}, ty.vec2<f32>()),
- Construct(Source{{12, 40}}, ty.vec3<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), vec2<f32>(), vec3<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(vec2<f32>, vec3<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4_Error_TooManyArgumentsVec3AndVec3) {
- auto* tc = vec4<f32>(Construct(Source{{12, 34}}, ty.vec3<f32>()),
- Construct(Source{{12, 40}}, ty.vec3<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), vec3<f32>(), vec3<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec4<f32>' with 6 component(s)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(vec3<f32>, vec3<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec4_Error_InvalidArgumentType) {
- auto* tc = vec4<f32>(Construct(Source{{12, 34}}, ty.mat2x2<f32>()));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec4<f32>(), mat2x2<f32>()));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: expected vector or scalar type in vector "
- "constructor; found: mat2x2<f32>");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec4<f32>(mat2x2<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec4_Success_ZeroValue) {
@@ -1590,13 +1569,13 @@
TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_NestedVectorConstructors_InnerError) {
- auto* tc = vec4<f32>(
- vec4<f32>(1_f, 1_f, vec3<f32>(Expr(Source{{12, 34}}, 1_f), Expr(Source{{12, 34}}, 1_f))),
- 1_f);
- WrapInFunction(tc);
+ WrapInFunction(vec4<f32>(vec4<f32>(1_f, 1_f, //
+ Construct(Source{{12, 34}}, ty.vec3<f32>(), 1_f, 1_f)),
+ 1_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: attempted to construct 'vec3<f32>' with 2 component(s)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<f32>(f32, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_NestedVectorConstructors_Success) {
@@ -1615,13 +1594,11 @@
auto* alias = Alias("UnsignedInt", ty.u32());
Global("uint_var", ty.Of(alias), ast::StorageClass::kPrivate);
- auto* tc = vec2<f32>(Expr(Source{{12, 34}}, "uint_var"));
+ auto* tc = Construct(Source{{12, 34}}, ty.vec2<f32>(), "uint_var");
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'f32', found 'u32'");
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for vec2<f32>(u32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vector_Alias_Argument_Success) {
@@ -1640,13 +1617,11 @@
// vec2<Float32>(1.0f, 1u)
auto* vec_type = ty.vec(ty.Of(f32_alias), 2);
- auto* tc = Construct(Source{{12, 34}}, vec_type, 1_f, Expr(Source{{12, 40}}, 1_u));
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, vec_type, 1_f, 1_u));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:40 error: type in vector constructor does not match vector "
- "type: expected 'f32', found 'u32'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec2<f32>(f32, u32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vector_ElementTypeAlias_Success) {
@@ -1666,13 +1641,11 @@
// vec3<u32>(vec<Float32>(), 1.0f)
auto* vec_type = ty.vec(ty.Of(f32_alias), 2);
- auto* tc = vec3<u32>(Construct(Source{{12, 34}}, vec_type), 1_f);
- WrapInFunction(tc);
+ WrapInFunction(Construct(Source{{12, 34}}, ty.vec3<u32>(), Construct(vec_type), 1_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'u32', found 'f32'");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("12:34 error: no matching constructor for vec3<u32>(vec2<f32>, f32)"));
}
TEST_F(ResolverTypeConstructorValidationTest,
@@ -1946,10 +1919,10 @@
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVectorElementTypeWithoutArgs) {
- WrapInFunction(Construct(create<ast::Vector>(Source{{12, 34}}, nullptr, 3)));
+ WrapInFunction(Construct(Source{{12, 34}}, create<ast::Vector>(nullptr, 3)));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for vec3()"));
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec2ElementTypeFromScalarsMismatch) {
@@ -1958,11 +1931,7 @@
Expr(Source{{1, 3}}, 2_u)));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(
- r()->error(),
- R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
-1:2 note: argument 0 has type i32
-1:3 note: argument 1 has type u32)");
+ EXPECT_THAT(r()->error(), HasSubstr("1:1 error: no matching constructor for vec2(i32, u32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec3ElementTypeFromScalarsMismatch) {
@@ -1972,12 +1941,8 @@
Expr(Source{{1, 4}}, 3_i)));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(
- r()->error(),
- R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
-1:2 note: argument 0 has type i32
-1:3 note: argument 1 has type u32
-1:4 note: argument 2 has type i32)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("1:1 error: no matching constructor for vec3(i32, u32, i32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec3ElementTypeFromScalarAndVec2Mismatch) {
@@ -1986,11 +1951,8 @@
Construct(Source{{1, 3}}, ty.vec2<f32>(), 2_f, 3_f)));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(
- r()->error(),
- R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
-1:2 note: argument 0 has type i32
-1:3 note: argument 1 has type vec2<f32>)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("1:1 error: no matching constructor for vec3(i32, vec2<f32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec4ElementTypeFromScalarsMismatch) {
@@ -2001,13 +1963,8 @@
Expr(Source{{1, 5}}, 4_i)));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(
- r()->error(),
- R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
-1:2 note: argument 0 has type i32
-1:3 note: argument 1 has type i32
-1:4 note: argument 2 has type f32
-1:5 note: argument 3 has type i32)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("1:1 error: no matching constructor for vec4(i32, i32, f32, i32)"));
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec4ElementTypeFromScalarAndVec3Mismatch) {
@@ -2016,11 +1973,8 @@
Construct(Source{{1, 3}}, ty.vec3<u32>(), 2_u, 3_u, 4_u)));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(
- r()->error(),
- R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
-1:2 note: argument 0 has type i32
-1:3 note: argument 1 has type vec3<u32>)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("1:1 error: no matching constructor for vec4(i32, vec3<u32>)"));
}
TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec4ElementTypeFromVec2AndVec2Mismatch) {
@@ -2029,11 +1983,8 @@
Construct(Source{{1, 3}}, ty.vec2<u32>(), 3_u, 4_u)));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(
- r()->error(),
- R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
-1:2 note: argument 0 has type vec2<i32>
-1:3 note: argument 1 has type vec2<u32>)");
+ EXPECT_THAT(r()->error(),
+ HasSubstr("1:1 error: no matching constructor for vec4(vec2<i32>, vec2<u32>)"));
}
} // namespace VectorConstructor
@@ -2058,22 +2009,22 @@
std::stringstream args_tys;
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns - 1; i++) {
+ for (uint32_t i = 0; i < param.columns - 1; i++) {
auto* vec_type = ty.vec<f32>(param.rows);
- args.push_back(Construct(Source{{12, i}}, vec_type));
- if (i > 1) {
+ args.push_back(Construct(vec_type));
+ if (i > 0) {
args_tys << ", ";
}
args_tys << "vec" << param.rows << "<f32>";
}
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " + MatrixStr(param) +
- "(" + args_tys.str() + ")\n\n3 candidates available:"));
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for " +
+ MatrixStr(param) + "(" + args_tys.str() + ")"));
}
TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_TooFewArguments) {
@@ -2083,21 +2034,21 @@
std::stringstream args_tys;
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns * param.rows - 1; i++) {
- args.push_back(Construct(Source{{12, i}}, ty.f32()));
- if (i > 1) {
+ for (uint32_t i = 0; i < param.columns * param.rows - 1; i++) {
+ args.push_back(Construct(ty.f32()));
+ if (i > 0) {
args_tys << ", ";
}
args_tys << "f32";
}
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " + MatrixStr(param) +
- "(" + args_tys.str() + ")\n\n3 candidates available:"));
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for " +
+ MatrixStr(param) + "(" + args_tys.str() + ")"));
}
TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooManyArguments) {
@@ -2107,22 +2058,22 @@
std::stringstream args_tys;
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns + 1; i++) {
+ for (uint32_t i = 0; i < param.columns + 1; i++) {
auto* vec_type = ty.vec<f32>(param.rows);
- args.push_back(Construct(Source{{12, i}}, vec_type));
- if (i > 1) {
+ args.push_back(Construct(vec_type));
+ if (i > 0) {
args_tys << ", ";
}
args_tys << "vec" << param.rows << "<f32>";
}
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " + MatrixStr(param) +
- "(" + args_tys.str() + ")\n\n3 candidates available:"));
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for " +
+ MatrixStr(param) + "(" + args_tys.str() + ")"));
}
TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_TooManyArguments) {
@@ -2132,21 +2083,21 @@
std::stringstream args_tys;
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns * param.rows + 1; i++) {
- args.push_back(Construct(Source{{12, i}}, ty.f32()));
- if (i > 1) {
+ for (uint32_t i = 0; i < param.columns * param.rows + 1; i++) {
+ args.push_back(Construct(ty.f32()));
+ if (i > 0) {
args_tys << ", ";
}
args_tys << "f32";
}
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " + MatrixStr(param) +
- "(" + args_tys.str() + ")\n\n3 candidates available:"));
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for " +
+ MatrixStr(param) + "(" + args_tys.str() + ")"));
}
TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_InvalidArgumentType) {
@@ -2156,22 +2107,22 @@
std::stringstream args_tys;
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns; i++) {
+ for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = ty.vec<u32>(param.rows);
- args.push_back(Construct(Source{{12, i}}, vec_type));
- if (i > 1) {
+ args.push_back(Construct(vec_type));
+ if (i > 0) {
args_tys << ", ";
}
args_tys << "vec" << param.rows << "<u32>";
}
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " + MatrixStr(param) +
- "(" + args_tys.str() + ")\n\n3 candidates available:"));
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for " +
+ MatrixStr(param) + "(" + args_tys.str() + ")"));
}
TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_InvalidArgumentType) {
@@ -2181,21 +2132,21 @@
std::stringstream args_tys;
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns; i++) {
- args.push_back(Expr(Source{{12, i}}, 1_u));
- if (i > 1) {
+ for (uint32_t i = 0; i < param.columns; i++) {
+ args.push_back(Expr(1_u));
+ if (i > 0) {
args_tys << ", ";
}
args_tys << "u32";
}
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " + MatrixStr(param) +
- "(" + args_tys.str() + ")\n\n3 candidates available:"));
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for " +
+ MatrixStr(param) + "(" + args_tys.str() + ")"));
}
TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooFewRowsInVectorArgument) {
@@ -2210,10 +2161,10 @@
std::stringstream args_tys;
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns - 1; i++) {
+ for (uint32_t i = 0; i < param.columns; i++) {
auto* valid_vec_type = ty.vec<f32>(param.rows);
- args.push_back(Construct(Source{{12, i}}, valid_vec_type));
- if (i > 1) {
+ args.push_back(Construct(valid_vec_type));
+ if (i > 0) {
args_tys << ", ";
}
args_tys << "vec" << param.rows << "<f32>";
@@ -2224,12 +2175,12 @@
args_tys << ", vec" << (param.rows - 1) << "<f32>";
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " + MatrixStr(param) +
- "(" + args_tys.str() + ")\n\n3 candidates available:"));
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for " +
+ MatrixStr(param) + "(" + args_tys.str() + ")"));
}
TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooManyRowsInVectorArgument) {
@@ -2244,26 +2195,25 @@
std::stringstream args_tys;
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns - 1; i++) {
+ for (uint32_t i = 0; i < param.columns; i++) {
auto* valid_vec_type = ty.vec<f32>(param.rows);
- args.push_back(Construct(Source{{12, i}}, valid_vec_type));
- if (i > 1) {
+ args.push_back(Construct(valid_vec_type));
+ if (i > 0) {
args_tys << ", ";
}
args_tys << "vec" << param.rows << "<f32>";
}
- const size_t kInvalidLoc = 2 * (param.columns - 1);
auto* invalid_vec_type = ty.vec<f32>(param.rows + 1);
- args.push_back(Construct(Source{{12, kInvalidLoc}}, invalid_vec_type));
+ args.push_back(Construct(invalid_vec_type));
args_tys << ", vec" << (param.rows + 1) << "<f32>";
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " + MatrixStr(param) +
- "(" + args_tys.str() + ")\n\n3 candidates available:"));
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for " +
+ MatrixStr(param) + "(" + args_tys.str() + ")"));
}
TEST_P(MatrixConstructorTest, Expr_Constructor_ZeroValue_Success) {
@@ -2283,13 +2233,13 @@
const auto param = GetParam();
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns; i++) {
+ for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = ty.vec<f32>(param.rows);
- args.push_back(Construct(Source{{12, i}}, vec_type));
+ args.push_back(Construct(vec_type));
}
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(matrix_type, std::move(args));
WrapInFunction(tc);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2301,12 +2251,12 @@
const auto param = GetParam();
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns * param.rows; i++) {
- args.push_back(Construct(Source{{12, i}}, ty.f32()));
+ for (uint32_t i = 0; i < param.columns * param.rows; i++) {
+ args.push_back(Construct(ty.f32()));
}
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(matrix_type, std::move(args));
WrapInFunction(tc);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2320,22 +2270,22 @@
std::stringstream args_tys;
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns; i++) {
+ for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = ty.vec(ty.u32(), param.rows);
- args.push_back(Construct(Source{{12, i}}, vec_type));
- if (i > 1) {
+ args.push_back(Construct(vec_type));
+ if (i > 0) {
args_tys << ", ";
}
args_tys << "vec" << param.rows << "<u32>";
}
auto* matrix_type = ty.mat(ty.Of(f32_alias), param.columns, param.rows);
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " + MatrixStr(param) +
- "(" + args_tys.str() + ")\n\n3 candidates available:"));
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for " +
+ MatrixStr(param) + "(" + args_tys.str() + ")"));
}
TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Success) {
@@ -2345,9 +2295,9 @@
auto* f32_alias = Alias("Float32", ty.f32());
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns; i++) {
+ for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = ty.vec<f32>(param.rows);
- args.push_back(Construct(Source{{12, i}}, vec_type));
+ args.push_back(Construct(vec_type));
}
auto* matrix_type = ty.mat(ty.Of(f32_alias), param.columns, param.rows);
@@ -2359,18 +2309,13 @@
TEST_F(ResolverTypeConstructorValidationTest, Expr_MatrixConstructor_ArgumentTypeAlias_Error) {
auto* alias = Alias("VectorUnsigned2", ty.vec2<u32>());
- auto* tc = mat2x2<f32>(Construct(Source{{12, 34}}, ty.Of(alias)), vec2<f32>());
+ auto* tc = Construct(Source{{12, 34}}, ty.mat2x2<f32>(), Construct(ty.Of(alias)), vec2<f32>());
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- R"(12:34 error: no matching constructor mat2x2<f32>(vec2<u32>, vec2<f32>)
-
-3 candidates available:
- mat2x2<f32>()
- mat2x2<f32>(f32,...,f32) // 4 arguments
- mat2x2<f32>(vec2<f32>, vec2<f32>)
-)");
+ EXPECT_THAT(
+ r()->error(),
+ HasSubstr("12:34 error: no matching constructor for mat2x2<f32>(vec2<u32>, vec2<f32>)"));
}
TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentTypeAlias_Success) {
@@ -2380,8 +2325,8 @@
auto* vec_alias = Alias("VectorFloat2", vec_type);
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns; i++) {
- args.push_back(Construct(Source{{12, i}}, ty.Of(vec_alias)));
+ for (uint32_t i = 0; i < param.columns; i++) {
+ args.push_back(Construct(ty.Of(vec_alias)));
}
auto* tc = Construct(Source{}, matrix_type, std::move(args));
@@ -2397,21 +2342,21 @@
std::stringstream args_tys;
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns; i++) {
+ for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = ty.vec(ty.Of(f32_alias), param.rows);
- args.push_back(Construct(Source{{12, i}}, vec_type));
- if (i > 1) {
+ args.push_back(Construct(vec_type));
+ if (i > 0) {
args_tys << ", ";
}
args_tys << "vec" << param.rows << "<u32>";
}
- auto* tc = Construct(Source{}, matrix_type, std::move(args));
+ auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
WrapInFunction(tc);
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " + MatrixStr(param) +
- "(" + args_tys.str() + ")\n\n3 candidates available:"));
+ EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching constructor for " +
+ MatrixStr(param) + "(" + args_tys.str() + ")"));
}
TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Success) {
@@ -2419,9 +2364,9 @@
auto* f32_alias = Alias("Float32", ty.f32());
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns; i++) {
+ for (uint32_t i = 0; i < param.columns; i++) {
auto* vec_type = ty.vec(ty.Of(f32_alias), param.rows);
- args.push_back(Construct(Source{{12, i}}, vec_type));
+ args.push_back(Construct(vec_type));
}
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
@@ -2435,7 +2380,7 @@
const auto param = GetParam();
ast::ExpressionList args;
- for (uint32_t i = 1; i <= param.columns; i++) {
+ for (uint32_t i = 0; i < param.columns; i++) {
args.push_back(Construct(ty.vec<f32>(param.rows)));
}
@@ -2464,20 +2409,21 @@
const auto param = GetParam();
std::stringstream err;
- err << "12:34 error: cannot infer matrix element type, as constructor "
- "arguments have different types";
+ err << "12:34 error: no matching constructor for mat" << param.columns << "x" << param.rows
+ << "(";
ast::ExpressionList args;
for (uint32_t i = 0; i < param.columns; i++) {
- err << "\n";
- auto src = Source{{1, 10 + i}};
+ if (i > 0) {
+ err << ", ";
+ }
if (i == 1) {
// Odd one out
- args.push_back(Construct(src, ty.vec<i32>(param.rows)));
- err << src << " note: argument " << i << " has type vec" << param.rows << "<i32>";
+ args.push_back(Construct(ty.vec<i32>(param.rows)));
+ err << "vec" << param.rows << "<i32>";
} else {
- args.push_back(Construct(src, ty.vec<f32>(param.rows)));
- err << src << " note: argument " << i << " has type vec" << param.rows << "<f32>";
+ args.push_back(Construct(ty.vec<f32>(param.rows)));
+ err << "vec" << param.rows << "<f32>";
}
}
@@ -2485,33 +2431,37 @@
WrapInFunction(Construct(Source{{12, 34}}, matrix_type, std::move(args)));
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), err.str());
+ EXPECT_THAT(r()->error(), HasSubstr(err.str()));
}
TEST_P(MatrixConstructorTest, CannotInferElementTypeFromScalars_Mismatch) {
const auto param = GetParam();
std::stringstream err;
- err << "12:34 error: cannot infer matrix element type, as constructor "
- "arguments have different types";
+ err << "12:34 error: no matching constructor for mat" << param.columns << "x" << param.rows
+ << "(";
+
ast::ExpressionList args;
for (uint32_t i = 0; i < param.rows * param.columns; i++) {
- err << "\n";
- auto src = Source{{1, 10 + i}};
+ if (i > 0) {
+ err << ", ";
+ }
if (i == 3) {
- args.push_back(Expr(src, static_cast<i32>(i))); // The odd one out
- err << src << " note: argument " << i << " has type i32";
+ args.push_back(Expr(static_cast<i32>(i))); // The odd one out
+ err << "i32";
} else {
- args.push_back(Expr(src, static_cast<f32>(i)));
- err << src << " note: argument " << i << " has type f32";
+ args.push_back(Expr(static_cast<f32>(i)));
+ err << "f32";
}
}
+ err << ")";
+
auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
WrapInFunction(Construct(Source{{12, 34}}, matrix_type, std::move(args)));
EXPECT_FALSE(r()->Resolve());
- EXPECT_THAT(r()->error(), err.str());
+ EXPECT_THAT(r()->error(), HasSubstr(err.str()));
}
INSTANTIATE_TEST_SUITE_P(ResolverTypeConstructorValidationTest,
@@ -2729,7 +2679,7 @@
WrapInFunction(CallStmt(Construct(Source{{12, 34}}, ty.f32(), 1_i)));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: type cast evaluated but not used");
+ EXPECT_EQ(r()->error(), "12:34 error: type conversion evaluated but not used");
}
} // namespace
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index 90e18e1..26b705f 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -662,6 +662,24 @@
EXPECT_EQ(r()->error(), "error: cannot use builtin 'max' as type");
}
+TEST_F(ResolverTypeValidationTest, F16TypeUsedWithExtension) {
+ // enable f16;
+ // var<private> v : f16;
+ Enable(ast::Extension::kF16);
+
+ Global("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);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "error: f16 used without 'f16' extension enabled");
+}
+
namespace GetCanonicalTests {
struct Params {
builder::ast_type_func_ptr create_ast_type;
@@ -719,19 +737,29 @@
} // namespace GetCanonicalTests
-namespace MultisampledTextureTests {
+namespace SampledTextureTests {
struct DimensionParams {
ast::TextureDimension dim;
bool is_valid;
};
-static constexpr DimensionParams dimension_cases[] = {
- DimensionParams{ast::TextureDimension::k1d, false},
- DimensionParams{ast::TextureDimension::k2d, true},
- DimensionParams{ast::TextureDimension::k2dArray, false},
- DimensionParams{ast::TextureDimension::k3d, false},
- DimensionParams{ast::TextureDimension::kCube, false},
- DimensionParams{ast::TextureDimension::kCubeArray, false}};
+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)});
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
+ SampledTextureDimensionTest,
+ testing::Values( //
+ DimensionParams{ast::TextureDimension::k1d, true},
+ DimensionParams{ast::TextureDimension::k2d, true},
+ DimensionParams{ast::TextureDimension::k2dArray, true},
+ DimensionParams{ast::TextureDimension::k3d, true},
+ DimensionParams{ast::TextureDimension::kCube, true},
+ DimensionParams{ast::TextureDimension::kCubeArray, true}));
using MultisampledTextureDimensionTest = ResolverTestWithParam<DimensionParams>;
TEST_P(MultisampledTextureDimensionTest, All) {
@@ -748,7 +776,13 @@
}
INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
MultisampledTextureDimensionTest,
- testing::ValuesIn(dimension_cases));
+ testing::Values( //
+ DimensionParams{ast::TextureDimension::k1d, false},
+ DimensionParams{ast::TextureDimension::k2d, true},
+ DimensionParams{ast::TextureDimension::k2dArray, false},
+ DimensionParams{ast::TextureDimension::k3d, false},
+ DimensionParams{ast::TextureDimension::kCube, false},
+ DimensionParams{ast::TextureDimension::kCubeArray, false}));
struct TypeParams {
builder::ast_type_func_ptr type_func;
@@ -778,6 +812,26 @@
TypeParamsFor<alias<mat3x3<f32>>>(false),
};
+using SampledTextureTypeTest = ResolverTestWithParam<TypeParams>;
+TEST_P(SampledTextureTypeTest, All) {
+ auto& params = GetParam();
+ Global(Source{{12, 34}}, "a",
+ ty.sampled_texture(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();
+ } else {
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "12:34 error: texture_2d<type>: type must be f32, "
+ "i32 or u32");
+ }
+}
+INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
+ SampledTextureTypeTest,
+ testing::ValuesIn(type_cases));
+
using MultisampledTextureTypeTest = ResolverTestWithParam<TypeParams>;
TEST_P(MultisampledTextureTypeTest, All) {
auto& params = GetParam();
@@ -798,7 +852,7 @@
MultisampledTextureTypeTest,
testing::ValuesIn(type_cases));
-} // namespace MultisampledTextureTests
+} // namespace SampledTextureTests
namespace StorageTextureTests {
struct DimensionParams {
diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc
new file mode 100644
index 0000000..6188521
--- /dev/null
+++ b/src/tint/resolver/uniformity.cc
@@ -0,0 +1,1563 @@
+// 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/resolver/uniformity.h"
+
+#include <limits>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+#include "src/tint/program_builder.h"
+#include "src/tint/resolver/dependency_graph.h"
+#include "src/tint/scope_stack.h"
+#include "src/tint/sem/block_statement.h"
+#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/info.h"
+#include "src/tint/sem/loop_statement.h"
+#include "src/tint/sem/statement.h"
+#include "src/tint/sem/switch_statement.h"
+#include "src/tint/sem/type_constructor.h"
+#include "src/tint/sem/type_conversion.h"
+#include "src/tint/sem/variable.h"
+#include "src/tint/utils/block_allocator.h"
+#include "src/tint/utils/map.h"
+#include "src/tint/utils/unique_vector.h"
+
+// Set to `1` to dump the uniformity graph for each function in graphviz format.
+#define TINT_DUMP_UNIFORMITY_GRAPH 0
+
+namespace tint::resolver {
+
+namespace {
+
+/// CallSiteTag describes the uniformity requirements on the call sites of a function.
+enum CallSiteTag {
+ CallSiteRequiredToBeUniform,
+ CallSiteNoRestriction,
+};
+
+/// FunctionTag describes a functions effects on uniformity.
+enum FunctionTag {
+ SubsequentControlFlowMayBeNonUniform,
+ ReturnValueMayBeNonUniform,
+ NoRestriction,
+};
+
+/// ParameterTag describes the uniformity requirements of values passed to a function parameter.
+enum ParameterTag {
+ ParameterRequiredToBeUniform,
+ ParameterRequiredToBeUniformForSubsequentControlFlow,
+ ParameterRequiredToBeUniformForReturnValue,
+ ParameterNoRestriction,
+};
+
+/// Node represents a node in the graph of control flow and value nodes within the analysis of a
+/// single function.
+struct Node {
+ /// Constructor
+ /// @param a the corresponding AST node
+ explicit Node(const ast::Node* a) : ast(a) {}
+
+#if TINT_DUMP_UNIFORMITY_GRAPH
+ /// The node tag.
+ std::string tag;
+#endif
+
+ /// Type describes the type of the node, which is used to determine additional diagnostic
+ /// information.
+ enum Type {
+ kRegular,
+ kFunctionCallArgument,
+ kFunctionCallPointerArgumentResult,
+ kFunctionCallReturnValue,
+ };
+
+ /// The type of the node.
+ Type type = kRegular;
+
+ /// `true` if this node represents a potential control flow change.
+ bool affects_control_flow = false;
+
+ /// The corresponding AST node, or nullptr.
+ const ast::Node* ast = nullptr;
+
+ /// The function call argument index, if applicable.
+ uint32_t arg_index;
+
+ /// The set of edges from this node to other nodes in the graph.
+ utils::UniqueVector<Node*> edges;
+
+ /// The node that this node was visited from, or nullptr if not visited.
+ Node* visited_from = nullptr;
+
+ /// Add an edge to the `to` node.
+ /// @param to the destination node
+ void AddEdge(Node* to) { edges.add(to); }
+};
+
+/// ParameterInfo holds information about the uniformity requirements and effects for a particular
+/// function parameter.
+struct ParameterInfo {
+ /// The semantic node in corresponds to this parameter.
+ const sem::Parameter* sem;
+ /// The parameter's uniformity requirements.
+ ParameterTag tag = ParameterNoRestriction;
+ /// Will be `true` if this function may cause the contents of this pointer parameter to become
+ /// non-uniform.
+ bool pointer_may_become_non_uniform = false;
+ /// The parameters that are required to be uniform for the contents of this pointer parameter to
+ /// be uniform at function exit.
+ std::vector<const sem::Parameter*> pointer_param_output_sources;
+ /// The node in the graph that corresponds to this parameter's initial value.
+ Node* init_value;
+ /// The node in the graph that corresponds to this parameter's output value (or nullptr).
+ Node* pointer_return_value = nullptr;
+};
+
+/// FunctionInfo holds information about the uniformity requirements and effects for a particular
+/// function, as well as the control flow graph.
+struct FunctionInfo {
+ /// Constructor
+ /// @param func the AST function
+ /// @param builder the program builder
+ FunctionInfo(const ast::Function* func, const ProgramBuilder* builder) {
+ name = builder->Symbols().NameFor(func->symbol);
+ callsite_tag = CallSiteNoRestriction;
+ function_tag = NoRestriction;
+
+ // Create special nodes.
+ required_to_be_uniform = CreateNode("RequiredToBeUniform");
+ may_be_non_uniform = CreateNode("MayBeNonUniform");
+ cf_start = CreateNode("CF_start");
+ cf_return = CreateNode("CF_return");
+ if (func->return_type) {
+ value_return = CreateNode("Value_return");
+ }
+
+ // Create nodes for parameters.
+ parameters.resize(func->params.size());
+ for (size_t i = 0; i < func->params.size(); i++) {
+ auto* param = func->params[i];
+ auto param_name = builder->Symbols().NameFor(param->symbol);
+ auto* sem = builder->Sem().Get<sem::Parameter>(param);
+ parameters[i].sem = sem;
+
+ Node* node_init;
+ if (sem->Type()->Is<sem::Pointer>()) {
+ node_init = CreateNode("ptrparam_" + name + "_init");
+ parameters[i].pointer_return_value = CreateNode("ptrparam_" + name + "_return");
+ local_var_decls.insert(sem);
+ } else {
+ node_init = CreateNode("param_" + name);
+ }
+ parameters[i].init_value = node_init;
+ variables.Set(sem, node_init);
+ }
+ }
+
+ /// The name of the function.
+ std::string name;
+
+ /// The call site uniformity requirements.
+ CallSiteTag callsite_tag;
+ /// The function's uniformity effects.
+ FunctionTag function_tag;
+ /// The uniformity requirements of the function's parameters.
+ std::vector<ParameterInfo> parameters;
+
+ /// The control flow graph.
+ utils::BlockAllocator<Node> nodes;
+
+ /// Special `RequiredToBeUniform` node.
+ Node* required_to_be_uniform;
+ /// Special `MayBeNonUniform` node.
+ Node* may_be_non_uniform;
+ /// Special `CF_start` node.
+ Node* cf_start;
+ /// Special `CF_return` node.
+ Node* cf_return;
+ /// Special `Value_return` node.
+ Node* value_return;
+
+ /// Map from variables to their value nodes in the graph, scoped with respect to control flow.
+ ScopeStack<const sem::Variable*, Node*> variables;
+
+ /// The set of a local read-write vars that are in scope at any given point in the process.
+ /// Includes pointer parameters.
+ std::unordered_set<const sem::Variable*> local_var_decls;
+
+ /// LoopSwitchInfo tracks information about the value of variables for a control flow construct.
+ struct LoopSwitchInfo {
+ /// The type of this control flow construct.
+ std::string type;
+ /// The input values for local variables at the start of this construct.
+ std::unordered_map<const sem::Variable*, Node*> var_in_nodes;
+ /// The exit values for local variables at the end of this construct.
+ std::unordered_map<const sem::Variable*, Node*> var_exit_nodes;
+ };
+
+ /// Map from control flow statements to the corresponding LoopSwitchInfo structure.
+ std::unordered_map<const sem::Statement*, LoopSwitchInfo> loop_switch_infos;
+
+ /// Create a new node.
+ /// @param tag a tag used to identify the node for debugging purposes
+ /// @param ast the optional AST node that this node corresponds to
+ /// @returns the new node
+ Node* CreateNode([[maybe_unused]] std::string tag, const ast::Node* ast = nullptr) {
+ auto* node = nodes.Create(ast);
+
+#if TINT_DUMP_UNIFORMITY_GRAPH
+ // Make the tag unique and set it.
+ // This only matters if we're dumping the graph.
+ std::string unique_tag = tag;
+ int suffix = 0;
+ while (tags_.count(unique_tag)) {
+ unique_tag = tag + "_$" + std::to_string(++suffix);
+ }
+ tags_.insert(unique_tag);
+ node->tag = name + "." + unique_tag;
+#endif
+
+ return node;
+ }
+
+ /// Reset the visited status of every node in the graph.
+ void ResetVisited() {
+ for (auto* node : nodes.Objects()) {
+ node->visited_from = nullptr;
+ }
+ }
+
+ private:
+ /// A list of tags that have already been used within the current function.
+ std::unordered_set<std::string> tags_;
+};
+
+/// UniformityGraph is used to analyze the uniformity requirements and effects of functions in a
+/// module.
+class UniformityGraph {
+ public:
+ /// Constructor.
+ /// @param builder the program to analyze
+ explicit UniformityGraph(ProgramBuilder* builder)
+ : builder_(builder), sem_(builder->Sem()), diagnostics_(builder->Diagnostics()) {}
+
+ /// Destructor.
+ ~UniformityGraph() {}
+
+ /// Build and analyze the graph to determine whether the program satisfies the uniformity
+ /// constraints of WGSL.
+ /// @param dependency_graph the dependency-ordered module-scope declarations
+ /// @returns true if all uniformity constraints are satisfied, otherise false
+ bool Build(const DependencyGraph& dependency_graph) {
+#if TINT_DUMP_UNIFORMITY_GRAPH
+ std::cout << "digraph G {\n";
+ std::cout << "rankdir=BT\n";
+#endif
+
+ // Process all functions in the module.
+ bool success = true;
+ for (auto* decl : dependency_graph.ordered_globals) {
+ if (auto* func = decl->As<ast::Function>()) {
+ if (!ProcessFunction(func)) {
+ success = false;
+ break;
+ }
+ }
+ }
+
+#if TINT_DUMP_UNIFORMITY_GRAPH
+ std::cout << "\n}\n";
+#endif
+
+ return success;
+ }
+
+ private:
+ const ProgramBuilder* builder_;
+ const sem::Info& sem_;
+ diag::List& diagnostics_;
+
+ /// Map of analyzed function results.
+ std::unordered_map<const ast::Function*, FunctionInfo> functions_;
+
+ /// The function currently being analyzed.
+ FunctionInfo* current_function_;
+
+ /// Create a new node.
+ /// @param tag a tag used to identify the node for debugging purposes.
+ /// @param ast the optional AST node that this node corresponds to
+ /// @returns the new node
+ Node* CreateNode(std::string tag, const ast::Node* ast = nullptr) {
+ return current_function_->CreateNode(tag, ast);
+ }
+
+ /// Process a function.
+ /// @param func the function to process
+ /// @returns true if there are no uniformity issues, false otherwise
+ bool ProcessFunction(const ast::Function* func) {
+ functions_.emplace(func, FunctionInfo(func, builder_));
+ current_function_ = &functions_.at(func);
+
+ // Process function body.
+ if (func->body) {
+ auto* cf = ProcessStatement(current_function_->cf_start, func->body);
+ current_function_->cf_return->AddEdge(cf);
+ }
+
+#if TINT_DUMP_UNIFORMITY_GRAPH
+ // Dump the graph for this function as a subgraph.
+ std::cout << "\nsubgraph cluster_" << current_function_->name << " {\n";
+ std::cout << " label=" << current_function_->name << ";";
+ for (auto* node : current_function_->nodes.Objects()) {
+ std::cout << "\n \"" << node->tag << "\";";
+ for (auto* edge : node->edges) {
+ std::cout << "\n \"" << node->tag << "\" -> \"" << edge->tag << "\";";
+ }
+ }
+ std::cout << "\n}\n";
+#endif
+
+ // Look at which nodes are reachable from "RequiredToBeUniform".
+ {
+ utils::UniqueVector<Node*> reachable;
+ Traverse(current_function_->required_to_be_uniform, &reachable);
+ if (reachable.contains(current_function_->may_be_non_uniform)) {
+ MakeError(*current_function_, current_function_->may_be_non_uniform);
+ return false;
+ }
+ if (reachable.contains(current_function_->cf_start)) {
+ current_function_->callsite_tag = CallSiteRequiredToBeUniform;
+ }
+
+ // Set the parameter tag to ParameterRequiredToBeUniform for each parameter node that
+ // was reachable.
+ for (size_t i = 0; i < func->params.size(); i++) {
+ auto* param = func->params[i];
+ if (reachable.contains(current_function_->variables.Get(sem_.Get(param)))) {
+ current_function_->parameters[i].tag = ParameterRequiredToBeUniform;
+ }
+ }
+ }
+
+ // Look at which nodes are reachable from "CF_return"
+ {
+ utils::UniqueVector<Node*> reachable;
+ Traverse(current_function_->cf_return, &reachable);
+ if (reachable.contains(current_function_->may_be_non_uniform)) {
+ current_function_->function_tag = SubsequentControlFlowMayBeNonUniform;
+ }
+
+ // Set the parameter tag to ParameterRequiredToBeUniformForSubsequentControlFlow for
+ // each parameter node that was reachable.
+ for (size_t i = 0; i < func->params.size(); i++) {
+ auto* param = func->params[i];
+ if (reachable.contains(current_function_->variables.Get(sem_.Get(param)))) {
+ current_function_->parameters[i].tag =
+ ParameterRequiredToBeUniformForSubsequentControlFlow;
+ }
+ }
+ }
+
+ // If "Value_return" exists, look at which nodes are reachable from it
+ if (current_function_->value_return) {
+ utils::UniqueVector<Node*> reachable;
+ Traverse(current_function_->value_return, &reachable);
+ if (reachable.contains(current_function_->may_be_non_uniform)) {
+ current_function_->function_tag = ReturnValueMayBeNonUniform;
+ }
+
+ // Set the parameter tag to ParameterRequiredToBeUniformForReturnValue for each
+ // parameter node that was reachable.
+ for (size_t i = 0; i < func->params.size(); i++) {
+ auto* param = func->params[i];
+ if (reachable.contains(current_function_->variables.Get(sem_.Get(param)))) {
+ current_function_->parameters[i].tag =
+ ParameterRequiredToBeUniformForReturnValue;
+ }
+ }
+ }
+
+ // Traverse the graph for each pointer parameter.
+ for (size_t i = 0; i < func->params.size(); i++) {
+ if (current_function_->parameters[i].pointer_return_value == nullptr) {
+ continue;
+ }
+
+ // Reset "visited" state for all nodes.
+ current_function_->ResetVisited();
+
+ utils::UniqueVector<Node*> reachable;
+ Traverse(current_function_->parameters[i].pointer_return_value, &reachable);
+ if (reachable.contains(current_function_->may_be_non_uniform)) {
+ current_function_->parameters[i].pointer_may_become_non_uniform = true;
+ }
+
+ // Check every other parameter to see if they feed into this parameter's final value.
+ for (size_t j = 0; j < func->params.size(); j++) {
+ auto* param_source = sem_.Get<sem::Parameter>(func->params[j]);
+ if (reachable.contains(current_function_->parameters[j].init_value)) {
+ current_function_->parameters[i].pointer_param_output_sources.push_back(
+ param_source);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /// Process a statement, returning the new control flow node.
+ /// @param cf the input control flow node
+ /// @param stmt the statement to process d
+ /// @returns the new control flow node
+ Node* ProcessStatement(Node* cf, const ast::Statement* stmt) {
+ return Switch(
+ stmt,
+
+ [&](const ast::AssignmentStatement* a) {
+ auto [cf1, v1] = ProcessExpression(cf, a->rhs);
+ if (a->lhs->Is<ast::PhonyExpression>()) {
+ return cf1;
+ } else {
+ auto [cf2, l2] = ProcessLValueExpression(cf1, a->lhs);
+ l2->AddEdge(v1);
+ return cf2;
+ }
+ },
+
+ [&](const ast::BlockStatement* b) {
+ std::unordered_map<const sem::Variable*, Node*> scoped_assignments;
+ {
+ // Push a new scope for variable assignments in the block.
+ current_function_->variables.Push();
+ TINT_DEFER(current_function_->variables.Pop());
+
+ for (auto* s : b->statements) {
+ cf = ProcessStatement(cf, s);
+ if (!sem_.Get(s)->Behaviors().Contains(sem::Behavior::kNext)) {
+ break;
+ }
+ }
+
+ if (sem_.Get<sem::FunctionBlockStatement>(b)) {
+ // We've reached the end of the function body.
+ // Add edges from pointer parameter outputs to their current value.
+ for (auto param : current_function_->parameters) {
+ if (param.pointer_return_value) {
+ param.pointer_return_value->AddEdge(
+ current_function_->variables.Get(param.sem));
+ }
+ }
+ }
+
+ scoped_assignments = std::move(current_function_->variables.Top());
+ }
+
+ // Propagate all variables assignments to the containing scope if the behavior is
+ // either 'Next' or 'Fallthrough'.
+ auto& behaviors = sem_.Get(b)->Behaviors();
+ if (behaviors.Contains(sem::Behavior::kNext) ||
+ behaviors.Contains(sem::Behavior::kFallthrough)) {
+ for (auto var : scoped_assignments) {
+ current_function_->variables.Set(var.first, var.second);
+ }
+ }
+
+ // Remove any variables declared in this scope from the set of in-scope variables.
+ for (auto* d : sem_.Get<sem::BlockStatement>(b)->Decls()) {
+ current_function_->local_var_decls.erase(sem_.Get<sem::LocalVariable>(d));
+ }
+
+ return cf;
+ },
+
+ [&](const ast::BreakStatement* b) {
+ // Find the loop or switch statement that we are in.
+ auto* parent = sem_.Get(b)
+ ->FindFirstParent<sem::SwitchStatement, sem::LoopStatement,
+ sem::ForLoopStatement>();
+ TINT_ASSERT(Resolver, current_function_->loop_switch_infos.count(parent));
+ auto& info = current_function_->loop_switch_infos.at(parent);
+
+ // Propagate variable values to the loop/switch exit nodes.
+ for (auto* var : current_function_->local_var_decls) {
+ // Skip variables that were declared inside this loop/switch.
+ if (auto* lv = var->As<sem::LocalVariable>();
+ lv &&
+ lv->Statement()->FindFirstParent([&](auto* s) { return s == parent; })) {
+ continue;
+ }
+
+ // Add an edge from the variable exit node to its value at this point.
+ auto* exit_node = utils::GetOrCreate(info.var_exit_nodes, var, [&]() {
+ auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
+ return CreateNode(name + "_value_" + info.type + "_exit");
+ });
+ exit_node->AddEdge(current_function_->variables.Get(var));
+ }
+
+ return cf;
+ },
+
+ [&](const ast::CallStatement* c) {
+ auto [cf1, _] = ProcessCall(cf, c->expr);
+ return cf1;
+ },
+
+ [&](const ast::CompoundAssignmentStatement* c) {
+ // The compound assignment statement `a += b` is equivalent to `a = a + b`.
+ auto [cf1, v1] = ProcessExpression(cf, c->lhs);
+ auto [cf2, v2] = ProcessExpression(cf1, c->rhs);
+ auto* result = CreateNode("binary_expr_result");
+ result->AddEdge(v1);
+ result->AddEdge(v2);
+
+ auto [cf3, l3] = ProcessLValueExpression(cf2, c->lhs);
+ l3->AddEdge(result);
+ return cf3;
+ },
+
+ [&](const ast::ContinueStatement* c) {
+ // Find the loop statement that we are in.
+ auto* parent =
+ sem_.Get(c)->FindFirstParent<sem::LoopStatement, sem::ForLoopStatement>();
+ TINT_ASSERT(Resolver, current_function_->loop_switch_infos.count(parent));
+ auto& info = current_function_->loop_switch_infos.at(parent);
+
+ // Propagate assignments to the loop input nodes.
+ for (auto* var : current_function_->local_var_decls) {
+ // Skip variables that were declared inside this loop.
+ if (auto* lv = var->As<sem::LocalVariable>();
+ lv &&
+ lv->Statement()->FindFirstParent([&](auto* s) { return s == parent; })) {
+ continue;
+ }
+
+ // Add an edge from the variable's loop input node to its value at this point.
+ TINT_ASSERT(Resolver, info.var_in_nodes.count(var));
+ auto* in_node = info.var_in_nodes.at(var);
+ auto* out_node = current_function_->variables.Get(var);
+ if (out_node != in_node) {
+ in_node->AddEdge(out_node);
+ }
+ }
+ return cf;
+ },
+
+ [&](const ast::DiscardStatement*) { return cf; },
+
+ [&](const ast::FallthroughStatement*) { return cf; },
+
+ [&](const ast::ForLoopStatement* f) {
+ auto* sem_loop = sem_.Get(f);
+ auto* cfx = CreateNode("loop_start");
+
+ // Insert the initializer before the loop.
+ auto* cf_init = cf;
+ if (f->initializer) {
+ cf_init = ProcessStatement(cf, f->initializer);
+ }
+ auto* cf_start = cf_init;
+
+ auto& info = current_function_->loop_switch_infos[sem_loop];
+ info.type = "forloop";
+
+ // Create input nodes for any variables declared before this loop.
+ for (auto* v : current_function_->local_var_decls) {
+ auto name = builder_->Symbols().NameFor(v->Declaration()->symbol);
+ auto* in_node = CreateNode(name + "_value_forloop_in");
+ in_node->AddEdge(current_function_->variables.Get(v));
+ info.var_in_nodes[v] = in_node;
+ current_function_->variables.Set(v, in_node);
+ }
+
+ // Insert the condition at the start of the loop body.
+ if (f->condition) {
+ auto [cf_cond, v] = ProcessExpression(cfx, f->condition);
+ auto* cf_condition_end = CreateNode("for_condition_CFend", f);
+ cf_condition_end->affects_control_flow = true;
+ cf_condition_end->AddEdge(v);
+ cf_start = cf_condition_end;
+
+ // Propagate assignments to the loop exit nodes.
+ for (auto* var : current_function_->local_var_decls) {
+ auto* exit_node = utils::GetOrCreate(info.var_exit_nodes, var, [&]() {
+ auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
+ return CreateNode(name + "_value_" + info.type + "_exit");
+ });
+ exit_node->AddEdge(current_function_->variables.Get(var));
+ }
+ }
+ auto* cf1 = ProcessStatement(cf_start, f->body);
+
+ // Insert the continuing statement at the end of the loop body.
+ if (f->continuing) {
+ auto* cf2 = ProcessStatement(cf1, f->continuing);
+ cfx->AddEdge(cf2);
+ } else {
+ cfx->AddEdge(cf1);
+ }
+ cfx->AddEdge(cf);
+
+ // Add edges from variable loop input nodes to their values at the end of the loop.
+ for (auto v : info.var_in_nodes) {
+ auto* in_node = v.second;
+ auto* out_node = current_function_->variables.Get(v.first);
+ if (out_node != in_node) {
+ in_node->AddEdge(out_node);
+ }
+ }
+
+ // Set each variable's exit node as its value in the outer scope.
+ for (auto v : info.var_exit_nodes) {
+ current_function_->variables.Set(v.first, v.second);
+ }
+
+ current_function_->loop_switch_infos.erase(sem_loop);
+
+ if (sem_loop->Behaviors() == sem::Behaviors{sem::Behavior::kNext}) {
+ return cf;
+ } else {
+ return cfx;
+ }
+ },
+
+ [&](const ast::IfStatement* i) {
+ auto* sem_if = sem_.Get(i);
+ auto [_, v_cond] = ProcessExpression(cf, i->condition);
+
+ // Add a diagnostic node to capture the control flow change.
+ auto* v = current_function_->CreateNode("if_stmt", i);
+ v->affects_control_flow = true;
+ v->AddEdge(v_cond);
+
+ std::unordered_map<const sem::Variable*, Node*> true_vars;
+ std::unordered_map<const sem::Variable*, Node*> false_vars;
+
+ // Helper to process a statement with a new scope for variable assignments.
+ // Populates `assigned_vars` with new nodes for any variables that are assigned in
+ // this statement.
+ auto process_in_scope =
+ [&](Node* cf_in, const ast::Statement* s,
+ std::unordered_map<const sem::Variable*, Node*>& assigned_vars) {
+ // Push a new scope for variable assignments.
+ current_function_->variables.Push();
+
+ // Process the statement.
+ auto* cf_out = ProcessStatement(cf_in, s);
+
+ assigned_vars = current_function_->variables.Top();
+
+ // Pop the scope and return.
+ current_function_->variables.Pop();
+ return cf_out;
+ };
+
+ auto* cf1 = process_in_scope(v, i->body, true_vars);
+
+ bool true_has_next = sem_.Get(i->body)->Behaviors().Contains(sem::Behavior::kNext);
+ bool false_has_next = true;
+
+ Node* cf2 = nullptr;
+ if (i->else_statement) {
+ cf2 = process_in_scope(v, i->else_statement, false_vars);
+
+ false_has_next =
+ sem_.Get(i->else_statement)->Behaviors().Contains(sem::Behavior::kNext);
+ }
+
+ // Update values for any variables assigned in the if or else blocks.
+ for (auto* var : current_function_->local_var_decls) {
+ // Skip variables not assigned in either block.
+ if (true_vars.count(var) == 0 && false_vars.count(var) == 0) {
+ continue;
+ }
+
+ // Create an exit node for the variable.
+ auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
+ auto* out_node = CreateNode(name + "_value_if_exit");
+
+ // Add edges to the assigned value or the initial value.
+ // Only add edges if the behavior for that block contains 'Next'.
+ if (true_has_next) {
+ if (true_vars.count(var)) {
+ out_node->AddEdge(true_vars.at(var));
+ } else {
+ out_node->AddEdge(current_function_->variables.Get(var));
+ }
+ }
+ if (false_has_next) {
+ if (false_vars.count(var)) {
+ out_node->AddEdge(false_vars.at(var));
+ } else {
+ out_node->AddEdge(current_function_->variables.Get(var));
+ }
+ }
+
+ current_function_->variables.Set(var, out_node);
+ }
+
+ if (sem_if->Behaviors() != sem::Behaviors{sem::Behavior::kNext}) {
+ auto* cf_end = CreateNode("if_CFend");
+ cf_end->AddEdge(cf1);
+ if (cf2) {
+ cf_end->AddEdge(cf2);
+ }
+ return cf_end;
+ }
+ return cf;
+ },
+
+ [&](const ast::IncrementDecrementStatement* i) {
+ // The increment/decrement statement `i++` is equivalent to `i = i + 1`.
+ auto [cf1, v1] = ProcessExpression(cf, i->lhs);
+ auto* result = CreateNode("incdec_result");
+ result->AddEdge(v1);
+ result->AddEdge(cf1);
+
+ auto [cf2, l2] = ProcessLValueExpression(cf1, i->lhs);
+ l2->AddEdge(result);
+ return cf2;
+ },
+
+ [&](const ast::LoopStatement* l) {
+ auto* sem_loop = sem_.Get(l);
+ auto* cfx = CreateNode("loop_start");
+
+ auto& info = current_function_->loop_switch_infos[sem_loop];
+ info.type = "loop";
+
+ // Create input nodes for any variables declared before this loop.
+ for (auto* v : current_function_->local_var_decls) {
+ auto name = builder_->Symbols().NameFor(v->Declaration()->symbol);
+ auto* in_node = CreateNode(name + "_value_loop_in");
+ in_node->AddEdge(current_function_->variables.Get(v));
+ info.var_in_nodes[v] = in_node;
+ current_function_->variables.Set(v, in_node);
+ }
+
+ auto* cf1 = ProcessStatement(cfx, l->body);
+ if (l->continuing) {
+ auto* cf2 = ProcessStatement(cf1, l->continuing);
+ cfx->AddEdge(cf2);
+ } else {
+ cfx->AddEdge(cf1);
+ }
+ cfx->AddEdge(cf);
+
+ // Add edges from variable loop input nodes to their values at the end of the loop.
+ for (auto v : info.var_in_nodes) {
+ auto* in_node = v.second;
+ auto* out_node = current_function_->variables.Get(v.first);
+ if (out_node != in_node) {
+ in_node->AddEdge(out_node);
+ }
+ }
+
+ // Set each variable's exit node as its value in the outer scope.
+ for (auto v : info.var_exit_nodes) {
+ current_function_->variables.Set(v.first, v.second);
+ }
+
+ current_function_->loop_switch_infos.erase(sem_loop);
+
+ if (sem_loop->Behaviors() == sem::Behaviors{sem::Behavior::kNext}) {
+ return cf;
+ } else {
+ return cfx;
+ }
+ },
+ [&](const ast::ReturnStatement* r) {
+ Node* cf_ret;
+ if (r->value) {
+ auto [cf1, v] = ProcessExpression(cf, r->value);
+ current_function_->cf_return->AddEdge(cf1);
+ current_function_->value_return->AddEdge(v);
+ cf_ret = cf1;
+ } else {
+ TINT_ASSERT(Resolver, cf != nullptr);
+ current_function_->cf_return->AddEdge(cf);
+ cf_ret = cf;
+ }
+
+ // Add edges from each pointer parameter output to its current value.
+ for (auto param : current_function_->parameters) {
+ if (param.pointer_return_value) {
+ param.pointer_return_value->AddEdge(
+ current_function_->variables.Get(param.sem));
+ }
+ }
+
+ return cf_ret;
+ },
+ [&](const ast::SwitchStatement* s) {
+ auto* sem_switch = sem_.Get(s);
+ auto [cfx, v_cond] = ProcessExpression(cf, s->condition);
+
+ // Add a diagnostic node to capture the control flow change.
+ auto* v = current_function_->CreateNode("switch_stmt", s);
+ v->affects_control_flow = true;
+ v->AddEdge(v_cond);
+
+ Node* cf_end = nullptr;
+ if (sem_switch->Behaviors() != sem::Behaviors{sem::Behavior::kNext}) {
+ cf_end = CreateNode("switch_CFend");
+ }
+
+ auto& info = current_function_->loop_switch_infos[sem_switch];
+ info.type = "switch";
+
+ auto* cf_n = v;
+ bool previous_case_has_fallthrough = false;
+ for (auto* c : s->body) {
+ auto* sem_case = sem_.Get(c);
+
+ if (previous_case_has_fallthrough) {
+ cf_n = ProcessStatement(cf_n, c->body);
+ } else {
+ current_function_->variables.Push();
+ cf_n = ProcessStatement(v, c->body);
+ }
+
+ if (cf_end) {
+ cf_end->AddEdge(cf_n);
+ }
+
+ bool has_fallthrough =
+ sem_case->Behaviors().Contains(sem::Behavior::kFallthrough);
+ if (!has_fallthrough) {
+ if (sem_case->Behaviors().Contains(sem::Behavior::kNext)) {
+ // Propagate variable values to the switch exit nodes.
+ for (auto* var : current_function_->local_var_decls) {
+ // Skip variables that were declared inside the switch.
+ if (auto* lv = var->As<sem::LocalVariable>();
+ lv && lv->Statement()->FindFirstParent(
+ [&](auto* st) { return st == sem_switch; })) {
+ continue;
+ }
+
+ // Add an edge from the variable exit node to its new value.
+ auto* exit_node =
+ utils::GetOrCreate(info.var_exit_nodes, var, [&]() {
+ auto name =
+ builder_->Symbols().NameFor(var->Declaration()->symbol);
+ return CreateNode(name + "_value_" + info.type + "_exit");
+ });
+ exit_node->AddEdge(current_function_->variables.Get(var));
+ }
+ }
+ current_function_->variables.Pop();
+ }
+ previous_case_has_fallthrough = has_fallthrough;
+ }
+
+ // Update nodes for any variables assigned in the switch statement.
+ for (auto var : info.var_exit_nodes) {
+ current_function_->variables.Set(var.first, var.second);
+ }
+
+ return cf_end ? cf_end : cf;
+ },
+ [&](const ast::VariableDeclStatement* decl) {
+ Node* node;
+ if (decl->variable->constructor) {
+ auto [cf1, v] = ProcessExpression(cf, decl->variable->constructor);
+ cf = cf1;
+ node = v;
+ } else {
+ node = cf;
+ }
+ current_function_->variables.Set(sem_.Get(decl->variable), node);
+
+ if (!decl->variable->is_const) {
+ current_function_->local_var_decls.insert(
+ sem_.Get<sem::LocalVariable>(decl->variable));
+ }
+
+ return cf;
+ },
+ [&](Default) {
+ TINT_ICE(Resolver, diagnostics_)
+ << "unknown statement type: " << std::string(stmt->TypeInfo().name);
+ return nullptr;
+ });
+ }
+
+ /// Process an identifier expression.
+ /// @param cf the input control flow node
+ /// @param ident the identifier expression to process
+ /// @returns a pair of (control flow node, value node)
+ std::pair<Node*, Node*> ProcessIdentExpression(Node* cf,
+ const ast::IdentifierExpression* ident) {
+ // Helper to check if the entry point attribute of `obj` indicates non-uniformity.
+ auto has_nonuniform_entry_point_attribute = [](auto* obj) {
+ // Only the num_workgroups and workgroup_id builtins are uniform.
+ if (auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(obj->attributes)) {
+ if (builtin->builtin == ast::Builtin::kNumWorkgroups ||
+ builtin->builtin == ast::Builtin::kWorkgroupId) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ auto name = builder_->Symbols().NameFor(ident->symbol);
+ auto* sem = sem_.Get<sem::VariableUser>(ident)->Variable();
+ auto* node = CreateNode(name + "_ident_expr", ident);
+ return Switch(
+ sem,
+
+ [&](const sem::Parameter* param) {
+ auto* user_func = param->Owner()->As<sem::Function>();
+ if (user_func && user_func->Declaration()->IsEntryPoint()) {
+ if (auto* str = param->Type()->As<sem::Struct>()) {
+ // We consider the whole struct to be non-uniform if any one of its members
+ // is non-uniform.
+ bool uniform = true;
+ for (auto* member : str->Members()) {
+ if (has_nonuniform_entry_point_attribute(member->Declaration())) {
+ uniform = false;
+ }
+ }
+ node->AddEdge(uniform ? cf : current_function_->may_be_non_uniform);
+ return std::make_pair(cf, node);
+ } else {
+ if (has_nonuniform_entry_point_attribute(param->Declaration())) {
+ node->AddEdge(current_function_->may_be_non_uniform);
+ } else {
+ node->AddEdge(cf);
+ }
+ return std::make_pair(cf, node);
+ }
+ } else {
+ auto* x = current_function_->variables.Get(param);
+ node->AddEdge(cf);
+ node->AddEdge(x);
+ return std::make_pair(cf, node);
+ }
+ },
+
+ [&](const sem::GlobalVariable* global) {
+ if (global->Declaration()->is_const || global->Access() == ast::Access::kRead) {
+ node->AddEdge(cf);
+ } else {
+ node->AddEdge(current_function_->may_be_non_uniform);
+ }
+ return std::make_pair(cf, node);
+ },
+
+ [&](const sem::LocalVariable* local) {
+ node->AddEdge(cf);
+ if (auto* x = current_function_->variables.Get(local)) {
+ node->AddEdge(x);
+ }
+ return std::make_pair(cf, node);
+ },
+
+ [&](Default) {
+ TINT_ICE(Resolver, diagnostics_)
+ << "unknown identifier expression type: " << std::string(sem->TypeInfo().name);
+ return std::pair<Node*, Node*>(nullptr, nullptr);
+ });
+ }
+
+ /// Process an expression.
+ /// @param cf the input control flow node
+ /// @param expr the expression to process
+ /// @returns a pair of (control flow node, value node)
+ std::pair<Node*, Node*> ProcessExpression(Node* cf, const ast::Expression* expr) {
+ return Switch(
+ expr,
+
+ [&](const ast::BinaryExpression* b) {
+ if (b->IsLogical()) {
+ // Short-circuiting binary operators are a special case.
+ auto [cf1, v1] = ProcessExpression(cf, b->lhs);
+
+ // Add a diagnostic node to capture the control flow change.
+ auto* v1_cf = current_function_->CreateNode("short_circuit_op", b);
+ v1_cf->affects_control_flow = true;
+ v1_cf->AddEdge(v1);
+
+ auto [cf2, v2] = ProcessExpression(v1_cf, b->rhs);
+ return std::pair<Node*, Node*>(cf2, v2);
+ } else {
+ auto [cf1, v1] = ProcessExpression(cf, b->lhs);
+ auto [cf2, v2] = ProcessExpression(cf1, b->rhs);
+ auto* result = CreateNode("binary_expr_result");
+ result->AddEdge(v1);
+ result->AddEdge(v2);
+ return std::pair<Node*, Node*>(cf2, result);
+ }
+ },
+
+ [&](const ast::BitcastExpression* b) { return ProcessExpression(cf, b->expr); },
+
+ [&](const ast::CallExpression* c) { return ProcessCall(cf, c); },
+
+ [&](const ast::IdentifierExpression* i) { return ProcessIdentExpression(cf, i); },
+
+ [&](const ast::IndexAccessorExpression* i) {
+ auto [cf1, v1] = ProcessExpression(cf, i->object);
+ auto [cf2, v2] = ProcessExpression(cf1, i->index);
+ auto* result = CreateNode("index_accessor_result");
+ result->AddEdge(v1);
+ result->AddEdge(v2);
+ return std::pair<Node*, Node*>(cf2, result);
+ },
+
+ [&](const ast::LiteralExpression*) { return std::make_pair(cf, cf); },
+
+ [&](const ast::MemberAccessorExpression* m) {
+ return ProcessExpression(cf, m->structure);
+ },
+
+ [&](const ast::UnaryOpExpression* u) {
+ if (u->op == ast::UnaryOp::kIndirection) {
+ // Cut the analysis short, since we only need to know the originating variable
+ // which is being accessed.
+ auto* source_var = sem_.Get(u)->SourceVariable();
+ auto* value = current_function_->variables.Get(source_var);
+ if (!value) {
+ value = cf;
+ }
+ return std::pair<Node*, Node*>(cf, value);
+ }
+ return ProcessExpression(cf, u->expr);
+ },
+
+ [&](Default) {
+ TINT_ICE(Resolver, diagnostics_)
+ << "unknown expression type: " << std::string(expr->TypeInfo().name);
+ return std::pair<Node*, Node*>(nullptr, nullptr);
+ });
+ }
+
+ /// Process an LValue expression.
+ /// @param cf the input control flow node
+ /// @param expr the expression to process
+ /// @returns a pair of (control flow node, variable node)
+ std::pair<Node*, Node*> ProcessLValueExpression(Node* cf, const ast::Expression* expr) {
+ return Switch(
+ expr,
+
+ [&](const ast::IdentifierExpression* i) {
+ auto name = builder_->Symbols().NameFor(i->symbol);
+ auto* sem = sem_.Get<sem::VariableUser>(i);
+ if (sem->Variable()->Is<sem::GlobalVariable>()) {
+ return std::make_pair(cf, current_function_->may_be_non_uniform);
+ } else if (auto* local = sem->Variable()->As<sem::LocalVariable>()) {
+ // Create a new value node for this variable.
+ auto* value = CreateNode(name + "_lvalue");
+ auto* old_value = current_function_->variables.Set(local, value);
+
+ // Aggregate values link back to their previous value, as they can never become
+ // uniform again.
+ if (!local->Type()->UnwrapRef()->is_scalar() && old_value) {
+ value->AddEdge(old_value);
+ }
+
+ return std::make_pair(cf, value);
+ } else {
+ TINT_ICE(Resolver, diagnostics_)
+ << "unknown lvalue identifier expression type: "
+ << std::string(sem->Variable()->TypeInfo().name);
+ return std::pair<Node*, Node*>(nullptr, nullptr);
+ }
+ },
+
+ [&](const ast::IndexAccessorExpression* i) {
+ auto [cf1, l1] = ProcessLValueExpression(cf, i->object);
+ auto [cf2, v2] = ProcessExpression(cf1, i->index);
+ l1->AddEdge(v2);
+ return std::pair<Node*, Node*>(cf2, l1);
+ },
+
+ [&](const ast::MemberAccessorExpression* m) {
+ return ProcessLValueExpression(cf, m->structure);
+ },
+
+ [&](const ast::UnaryOpExpression* u) {
+ if (u->op == ast::UnaryOp::kIndirection) {
+ // Cut the analysis short, since we only need to know the originating variable
+ // that is being written to.
+ auto* source_var = sem_.Get(u)->SourceVariable();
+ auto name = builder_->Symbols().NameFor(source_var->Declaration()->symbol);
+ auto* deref = CreateNode(name + "_deref");
+ auto* old_value = current_function_->variables.Set(source_var, deref);
+
+ // Aggregate values link back to their previous value, as they can never become
+ // uniform again.
+ if (!source_var->Type()->UnwrapRef()->UnwrapPtr()->is_scalar() && old_value) {
+ deref->AddEdge(old_value);
+ }
+
+ return std::pair<Node*, Node*>(cf, deref);
+ }
+ return ProcessLValueExpression(cf, u->expr);
+ },
+
+ [&](Default) {
+ TINT_ICE(Resolver, diagnostics_)
+ << "unknown lvalue expression type: " << std::string(expr->TypeInfo().name);
+ return std::pair<Node*, Node*>(nullptr, nullptr);
+ });
+ }
+
+ /// Process a function call expression.
+ /// @param cf the input control flow node
+ /// @param call the function call to process
+ /// @returns a pair of (control flow node, value node)
+ std::pair<Node*, Node*> ProcessCall(Node* cf, const ast::CallExpression* call) {
+ std::string name;
+ if (call->target.name) {
+ name = builder_->Symbols().NameFor(call->target.name->symbol);
+ } else {
+ name = call->target.type->FriendlyName(builder_->Symbols());
+ }
+
+ // Process call arguments
+ Node* cf_last_arg = cf;
+ std::vector<Node*> args;
+ for (size_t i = 0; i < call->args.size(); i++) {
+ auto [cf_i, arg_i] = ProcessExpression(cf_last_arg, call->args[i]);
+
+ // Capture the index of this argument in a new node.
+ // Note: This is an additional node that isn't described in the specification, for the
+ // purpose of providing diagnostic information.
+ Node* arg_node = CreateNode(name + "_arg_" + std::to_string(i), call);
+ arg_node->type = Node::kFunctionCallArgument;
+ arg_node->arg_index = static_cast<uint32_t>(i);
+ arg_node->AddEdge(arg_i);
+
+ cf_last_arg = cf_i;
+ args.push_back(arg_node);
+ }
+
+ // Note: This is an additional node that isn't described in the specification, for the
+ // purpose of providing diagnostic information.
+ Node* call_node = CreateNode(name + "_call", call);
+ call_node->AddEdge(cf_last_arg);
+
+ Node* result = CreateNode(name + "_return_value", call);
+ result->type = Node::kFunctionCallReturnValue;
+ Node* cf_after = CreateNode("CF_after_" + name, call);
+
+ // Get tags for the callee.
+ CallSiteTag callsite_tag = CallSiteNoRestriction;
+ FunctionTag function_tag = NoRestriction;
+ auto* sem = SemCall(call);
+ const FunctionInfo* func_info = nullptr;
+ Switch(
+ sem->Target(),
+ [&](const sem::Builtin* builtin) {
+ // Most builtins have no restrictions. The exceptions are barriers, derivatives, and
+ // some texture sampling builtins.
+ if (builtin->IsBarrier()) {
+ callsite_tag = CallSiteRequiredToBeUniform;
+ } else if (builtin->IsDerivative() ||
+ builtin->Type() == sem::BuiltinType::kTextureSample ||
+ builtin->Type() == sem::BuiltinType::kTextureSampleBias ||
+ builtin->Type() == sem::BuiltinType::kTextureSampleCompare) {
+ callsite_tag = CallSiteRequiredToBeUniform;
+ function_tag = ReturnValueMayBeNonUniform;
+ } else {
+ callsite_tag = CallSiteNoRestriction;
+ function_tag = NoRestriction;
+ }
+ },
+ [&](const sem::Function* func) {
+ // We must have already analyzed the user-defined function since we process
+ // functions in dependency order.
+ TINT_ASSERT(Resolver, functions_.count(func->Declaration()));
+ auto& info = functions_.at(func->Declaration());
+ callsite_tag = info.callsite_tag;
+ function_tag = info.function_tag;
+ func_info = &info;
+ },
+ [&](const sem::TypeConstructor*) {
+ callsite_tag = CallSiteNoRestriction;
+ function_tag = NoRestriction;
+ },
+ [&](const sem::TypeConversion*) {
+ callsite_tag = CallSiteNoRestriction;
+ function_tag = NoRestriction;
+ },
+ [&](Default) {
+ TINT_ICE(Resolver, diagnostics_) << "unhandled function call target: " << name;
+ });
+
+ if (callsite_tag == CallSiteRequiredToBeUniform) {
+ current_function_->required_to_be_uniform->AddEdge(call_node);
+ }
+ cf_after->AddEdge(call_node);
+
+ if (function_tag == SubsequentControlFlowMayBeNonUniform) {
+ cf_after->AddEdge(current_function_->may_be_non_uniform);
+ cf_after->affects_control_flow = true;
+ } else if (function_tag == ReturnValueMayBeNonUniform) {
+ result->AddEdge(current_function_->may_be_non_uniform);
+ }
+
+ result->AddEdge(cf_after);
+
+ // For each argument, add edges based on parameter tags.
+ for (size_t i = 0; i < args.size(); i++) {
+ if (func_info) {
+ switch (func_info->parameters[i].tag) {
+ case ParameterRequiredToBeUniform:
+ current_function_->required_to_be_uniform->AddEdge(args[i]);
+ break;
+ case ParameterRequiredToBeUniformForSubsequentControlFlow:
+ cf_after->AddEdge(args[i]);
+ args[i]->affects_control_flow = true;
+ break;
+ case ParameterRequiredToBeUniformForReturnValue:
+ result->AddEdge(args[i]);
+ break;
+ case ParameterNoRestriction:
+ break;
+ }
+
+ auto* sem_arg = sem_.Get(call->args[i]);
+ if (sem_arg->Type()->Is<sem::Pointer>()) {
+ auto* ptr_result =
+ CreateNode(name + "_ptrarg_" + std::to_string(i) + "_result", call);
+ ptr_result->type = Node::kFunctionCallPointerArgumentResult;
+ ptr_result->arg_index = static_cast<uint32_t>(i);
+ if (func_info->parameters[i].pointer_may_become_non_uniform) {
+ ptr_result->AddEdge(current_function_->may_be_non_uniform);
+ } else {
+ // Add edges from the resulting pointer value to any other arguments that
+ // feed it.
+ for (auto* source : func_info->parameters[i].pointer_param_output_sources) {
+ ptr_result->AddEdge(args[source->Index()]);
+ }
+ }
+
+ // Update the current stored value for this pointer argument.
+ auto* source_var = sem_arg->SourceVariable();
+ TINT_ASSERT(Resolver, source_var);
+ current_function_->variables.Set(source_var, ptr_result);
+ }
+ } else {
+ // All builtin function parameters are RequiredToBeUniformForReturnValue, as are
+ // parameters for type constructors and type conversions.
+ // The arrayLength() builtin is a special case, as there is currently no way for it
+ // to have a non-uniform return value.
+ auto* builtin = sem->Target()->As<sem::Builtin>();
+ if (!builtin || builtin->Type() != sem::BuiltinType::kArrayLength) {
+ result->AddEdge(args[i]);
+ }
+ }
+ }
+
+ return {cf_after, result};
+ }
+
+ /// Traverse a graph starting at `source`, inserting all visited nodes into `reachable` and
+ /// recording which node they were reached from.
+ /// @param source the starting node
+ /// @param reachable the set of reachable nodes to populate, if required
+ void Traverse(Node* source, utils::UniqueVector<Node*>* reachable = nullptr) {
+ std::vector<Node*> to_visit{source};
+
+ while (!to_visit.empty()) {
+ auto* node = to_visit.back();
+ to_visit.pop_back();
+
+ if (reachable) {
+ reachable->add(node);
+ }
+ for (auto* to : node->edges) {
+ if (to->visited_from == nullptr) {
+ to->visited_from = node;
+ to_visit.push_back(to);
+ }
+ }
+ }
+ }
+
+ /// Trace back along a path from `start` until finding a node that matches a predicate.
+ /// @param start the starting node
+ /// @param pred the predicate function
+ /// @returns the first node found that matches the predicate, or nullptr
+ template <typename F>
+ Node* TraceBackAlongPathUntil(Node* start, F&& pred) {
+ auto* current = start;
+ while (current) {
+ if (pred(current)) {
+ break;
+ }
+ current = current->visited_from;
+ }
+ return current;
+ }
+
+ /// Recursively descend through the function called by `call` and the functions that it calls in
+ /// order to find a call to a builtin function that requires uniformity.
+ const ast::CallExpression* FindBuiltinThatRequiresUniformity(const ast::CallExpression* call) {
+ auto* target = SemCall(call)->Target();
+ if (target->Is<sem::Builtin>()) {
+ // This is a call to a builtin, so we must be done.
+ return call;
+ } else if (auto* user = target->As<sem::Function>()) {
+ // This is a call to a user-defined function, so inspect the functions called by that
+ // function and look for one whose node has an edge from the RequiredToBeUniform node.
+ auto& target_info = functions_.at(user->Declaration());
+ for (auto* call_node : target_info.required_to_be_uniform->edges) {
+ if (call_node->type == Node::kRegular) {
+ auto* child_call = call_node->ast->As<ast::CallExpression>();
+ return FindBuiltinThatRequiresUniformity(child_call);
+ }
+ }
+ TINT_ASSERT(Resolver, false && "unable to find child call with uniformity requirement");
+ } else {
+ TINT_ASSERT(Resolver, false && "unexpected call expression type");
+ }
+ return nullptr;
+ }
+
+ /// Add diagnostic notes to show where control flow became non-uniform on the way to a node.
+ /// @param function the function being analyzed
+ /// @param required_to_be_uniform the node to traverse from
+ /// @param may_be_non_uniform the node to traverse to
+ void ShowCauseOfNonUniformity(FunctionInfo& function,
+ Node* required_to_be_uniform,
+ Node* may_be_non_uniform) {
+ // Traverse the graph to generate a path from the node to the source of non-uniformity.
+ function.ResetVisited();
+ Traverse(required_to_be_uniform);
+
+ // Get the source of the non-uniform value.
+ auto* non_uniform_source = may_be_non_uniform->visited_from;
+ TINT_ASSERT(Resolver, non_uniform_source);
+
+ // Show where the non-uniform value results in non-uniform control flow.
+ auto* control_flow = TraceBackAlongPathUntil(
+ non_uniform_source, [](Node* node) { return node->affects_control_flow; });
+ if (control_flow) {
+ if (auto* call = control_flow->ast->As<ast::CallExpression>()) {
+ if (control_flow->type == Node::kFunctionCallArgument) {
+ auto idx = control_flow->arg_index;
+ diagnostics_.add_note(diag::System::Resolver,
+ "non-uniform function call argument causes subsequent "
+ "control flow to be non-uniform",
+ call->args[idx]->source);
+
+ // Recurse into the target function.
+ if (auto* user = SemCall(call)->Target()->As<sem::Function>()) {
+ auto& callee = functions_.at(user->Declaration());
+ ShowCauseOfNonUniformity(callee, callee.cf_return,
+ callee.parameters[idx].init_value);
+ }
+ }
+ } else {
+ diagnostics_.add_note(diag::System::Resolver,
+ "control flow depends on non-uniform value",
+ control_flow->ast->source);
+ }
+ // TODO(jrprice): There are cases where the function with uniformity requirements is not
+ // actually inside this control flow construct, for example:
+ // - A conditional interrupt (e.g. break), with a barrier elsewhere in the loop
+ // - A conditional assignment to a variable, which is later used to guard a barrier
+ // In these cases, the diagnostics are not entirely accurate as they may not highlight
+ // the actual cause of divergence.
+ }
+
+ // Show the source of the non-uniform value.
+ Switch(
+ non_uniform_source->ast,
+ [&](const ast::IdentifierExpression* ident) {
+ std::string var_type = "";
+ auto* var = sem_.Get<sem::VariableUser>(ident)->Variable();
+ switch (var->StorageClass()) {
+ case ast::StorageClass::kStorage:
+ var_type = "read_write storage buffer ";
+ break;
+ case ast::StorageClass::kWorkgroup:
+ var_type = "workgroup storage variable ";
+ break;
+ case ast::StorageClass::kPrivate:
+ var_type = "module-scope private variable ";
+ break;
+ default:
+ if (ast::HasAttribute<ast::BuiltinAttribute>(
+ var->Declaration()->attributes)) {
+ var_type = "builtin ";
+ } else if (ast::HasAttribute<ast::LocationAttribute>(
+ var->Declaration()->attributes)) {
+ var_type = "user-defined input ";
+ } else {
+ // TODO(jrprice): Provide more info for this case.
+ }
+ break;
+ }
+ diagnostics_.add_note(diag::System::Resolver,
+ "reading from " + var_type + "'" +
+ builder_->Symbols().NameFor(ident->symbol) +
+ "' may result in a non-uniform value",
+ ident->source);
+ },
+ [&](const ast::CallExpression* c) {
+ auto target_name = builder_->Symbols().NameFor(
+ c->target.name->As<ast::IdentifierExpression>()->symbol);
+ switch (non_uniform_source->type) {
+ case Node::kRegular: {
+ diagnostics_.add_note(
+ diag::System::Resolver,
+ "calling '" + target_name +
+ "' may cause subsequent control flow to be non-uniform",
+ c->source);
+
+ // Recurse into the target function.
+ if (auto* user = SemCall(c)->Target()->As<sem::Function>()) {
+ auto& callee = functions_.at(user->Declaration());
+ ShowCauseOfNonUniformity(callee, callee.cf_return,
+ callee.may_be_non_uniform);
+ }
+ break;
+ }
+ case Node::kFunctionCallReturnValue: {
+ diagnostics_.add_note(
+ diag::System::Resolver,
+ "return value of '" + target_name + "' may be non-uniform", c->source);
+ break;
+ }
+ case Node::kFunctionCallPointerArgumentResult: {
+ diagnostics_.add_note(
+ diag::System::Resolver,
+ "pointer contents may become non-uniform after calling '" +
+ target_name + "'",
+ c->args[non_uniform_source->arg_index]->source);
+ break;
+ }
+ default: {
+ TINT_ICE(Resolver, diagnostics_) << "unhandled source of non-uniformity";
+ break;
+ }
+ }
+ },
+ [&](Default) {
+ TINT_ICE(Resolver, diagnostics_) << "unhandled source of non-uniformity";
+ });
+ }
+
+ /// Generate an error message for a uniformity issue.
+ /// @param function the function that the diagnostic is being produced for
+ /// @param source_node the node that has caused a uniformity issue in `function`
+ /// @param note `true` if the diagnostic should be emitted as a note
+ void MakeError(FunctionInfo& function, Node* source_node, bool note = false) {
+ // Helper to produce a diagnostic message with the severity required by this invocation of
+ // the `MakeError` function.
+ auto report = [&](Source source, std::string msg) {
+ // TODO(jrprice): Switch to error instead of warning when feedback has settled.
+ diag::Diagnostic error{};
+ error.severity = note ? diag::Severity::Note : diag::Severity::Warning;
+ error.system = diag::System::Resolver;
+ error.source = source;
+ error.message = msg;
+ diagnostics_.add(std::move(error));
+ };
+
+ // Traverse the graph to generate a path from RequiredToBeUniform to the source node.
+ function.ResetVisited();
+ Traverse(function.required_to_be_uniform);
+ TINT_ASSERT(Resolver, source_node->visited_from);
+
+ // Find a node that is required to be uniform that has a path to the source node.
+ auto* cause = TraceBackAlongPathUntil(source_node, [&](Node* node) {
+ return node->visited_from == function.required_to_be_uniform;
+ });
+
+ // The node will always have a corresponding call expression.
+ auto* call = cause->ast->As<ast::CallExpression>();
+ TINT_ASSERT(Resolver, call);
+ auto* target = SemCall(call)->Target();
+
+ std::string func_name;
+ if (auto* builtin = target->As<sem::Builtin>()) {
+ func_name = builtin->str();
+ } else if (auto* user = target->As<sem::Function>()) {
+ func_name = builder_->Symbols().NameFor(user->Declaration()->symbol);
+ }
+
+ if (cause->type == Node::kFunctionCallArgument) {
+ // The requirement was on a function parameter.
+ auto param_name = builder_->Symbols().NameFor(
+ target->Parameters()[cause->arg_index]->Declaration()->symbol);
+ report(call->args[cause->arg_index]->source,
+ "parameter '" + param_name + "' of '" + func_name + "' must be uniform");
+
+ // If this is a call to a user-defined function, add a note to show the reason that the
+ // parameter is required to be uniform.
+ if (auto* user = target->As<sem::Function>()) {
+ auto& next_function = functions_.at(user->Declaration());
+ Node* next_cause = next_function.parameters[cause->arg_index].init_value;
+ MakeError(next_function, next_cause, true);
+ }
+ } else {
+ // The requirement was on a function callsite.
+ report(call->source,
+ "'" + func_name + "' must only be called from uniform control flow");
+
+ // If this is a call to a user-defined function, add a note to show the builtin that
+ // causes the uniformity requirement.
+ auto* innermost_call = FindBuiltinThatRequiresUniformity(call);
+ if (innermost_call != call) {
+ auto* sem_call = SemCall(call);
+ auto* sem_innermost_call = SemCall(innermost_call);
+
+ // Determine whether the builtin is being called directly or indirectly.
+ bool indirect = false;
+ if (sem_call->Target()->As<sem::Function>() !=
+ sem_innermost_call->Stmt()->Function()) {
+ indirect = true;
+ }
+
+ auto* builtin = sem_innermost_call->Target()->As<sem::Builtin>();
+ diagnostics_.add_note(diag::System::Resolver,
+ "'" + func_name + "' requires uniformity because it " +
+ (indirect ? "indirectly " : "") + "calls " +
+ builtin->str(),
+ innermost_call->source);
+ }
+ }
+
+ // Show the cause of non-uniformity (starting at the top-level error).
+ if (!note) {
+ ShowCauseOfNonUniformity(function, function.required_to_be_uniform,
+ function.may_be_non_uniform);
+ }
+ }
+
+ // Helper for obtaining the sem::Call node for the ast::CallExpression
+ const sem::Call* SemCall(const ast::CallExpression* expr) const {
+ return sem_.Get(expr)->UnwrapMaterialize()->As<sem::Call>();
+ }
+};
+
+} // namespace
+
+bool AnalyzeUniformity(ProgramBuilder* builder, const DependencyGraph& dependency_graph) {
+ UniformityGraph graph(builder);
+ return graph.Build(dependency_graph);
+}
+
+} // namespace tint::resolver
diff --git a/src/tint/resolver/uniformity.h b/src/tint/resolver/uniformity.h
new file mode 100644
index 0000000..39827cf
--- /dev/null
+++ b/src/tint/resolver/uniformity.h
@@ -0,0 +1,36 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_RESOLVER_UNIFORMITY_H_
+#define SRC_TINT_RESOLVER_UNIFORMITY_H_
+
+// Forward declarations.
+namespace tint {
+namespace resolver {
+struct DependencyGraph;
+} // namespace resolver
+class ProgramBuilder;
+} // namespace tint
+
+namespace tint::resolver {
+
+/// Analyze the uniformity of a program.
+/// @param builder the program to analyze
+/// @param dependency_graph the dependency-ordered module-scope declarations
+/// @returns true if there are no uniformity issues, false otherwise
+bool AnalyzeUniformity(ProgramBuilder* builder, const resolver::DependencyGraph& dependency_graph);
+
+} // namespace tint::resolver
+
+#endif // SRC_TINT_RESOLVER_UNIFORMITY_H_
diff --git a/src/tint/resolver/uniformity_test.cc b/src/tint/resolver/uniformity_test.cc
new file mode 100644
index 0000000..4a71045
--- /dev/null
+++ b/src/tint/resolver/uniformity_test.cc
@@ -0,0 +1,6256 @@
+// 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 <memory>
+#include <string>
+#include <tuple>
+#include <utility>
+
+#include "src/tint/program_builder.h"
+#include "src/tint/reader/wgsl/parser.h"
+#include "src/tint/resolver/uniformity.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::resolver {
+namespace {
+
+class UniformityAnalysisTestBase {
+ protected:
+ /// Parse and resolve a WGSL shader.
+ /// @param src the WGSL source code
+ /// @param should_pass true if `src` should pass the analysis, otherwise false
+ void RunTest(std::string src, bool should_pass) {
+ auto file = std::make_unique<Source::File>("test", src);
+ auto program = reader::wgsl::Parse(file.get());
+
+ diag::Formatter::Style style;
+ style.print_newline_at_end = false;
+ error_ = diag::Formatter(style).format(program.Diagnostics());
+
+ bool valid = program.IsValid();
+ if (should_pass) {
+ EXPECT_TRUE(valid) << error_;
+ if (program.Diagnostics().count() == 1u) {
+ EXPECT_THAT(program.Diagnostics().str(), ::testing::HasSubstr("unreachable"));
+ } else {
+ EXPECT_EQ(program.Diagnostics().count(), 0u) << error_;
+ }
+ } else {
+ // TODO(jrprice): expect false when uniformity issues become errors.
+ EXPECT_TRUE(valid) << error_;
+ }
+ }
+
+ /// Build and resolve a program from a ProgramBuilder object.
+ /// @param builder the program builder
+ /// @returns true on success, false on failure
+ bool RunTest(ProgramBuilder&& builder) {
+ auto program = Program(std::move(builder));
+
+ diag::Formatter::Style style;
+ style.print_newline_at_end = false;
+ error_ = diag::Formatter(style).format(program.Diagnostics());
+
+ return program.IsValid();
+ }
+
+ /// The error message from the parser or resolver, if any.
+ std::string error_;
+};
+
+class UniformityAnalysisTest : public UniformityAnalysisTestBase, public ::testing::Test {};
+
+class BasicTest : public UniformityAnalysisTestBase,
+ public ::testing::TestWithParam<std::tuple<int, int>> {
+ public:
+ /// Enum for the if-statement condition guarding a function call.
+ enum Condition {
+ // Uniform conditions:
+ kTrue,
+ kFalse,
+ kLiteral,
+ kModuleLet,
+ kPipelineOverridable,
+ kFuncLetUniformRhs,
+ kFuncVarUniform,
+ kFuncUniformRetVal,
+ kUniformBuffer,
+ kROStorageBuffer,
+ kLastUniformCondition = kROStorageBuffer,
+ // MayBeNonUniform conditions:
+ kFuncLetNonUniformRhs,
+ kFuncVarNonUniform,
+ kFuncNonUniformRetVal,
+ kRWStorageBuffer,
+ // End of range marker:
+ kEndOfConditionRange,
+ };
+
+ /// Enum for the function call statement.
+ enum Function {
+ // NoRestrictionFunctions:
+ kUserNoRestriction,
+ kMin,
+ kTextureSampleLevel,
+ kLastNoRestrictionFunction = kTextureSampleLevel,
+ // RequiredToBeUniform functions:
+ kUserRequiredToBeUniform,
+ kWorkgroupBarrier,
+ kStorageBarrier,
+ kTextureSample,
+ kTextureSampleBias,
+ kTextureSampleCompare,
+ kDpdx,
+ kDpdxCoarse,
+ kDpdxFine,
+ kDpdy,
+ kDpdyCoarse,
+ kDpdyFine,
+ kFwidth,
+ kFwidthCoarse,
+ kFwidthFine,
+ // End of range marker:
+ kEndOfFunctionRange,
+ };
+
+ /// Convert a condition to its string representation.
+ static std::string ConditionToStr(Condition c) {
+ switch (c) {
+ case kTrue:
+ return "true";
+ case kFalse:
+ return "false";
+ case kLiteral:
+ return "7 == 7";
+ case kModuleLet:
+ return "module_let == 0";
+ case kPipelineOverridable:
+ return "pipeline_overridable == 0";
+ case kFuncLetUniformRhs:
+ return "let_uniform_rhs == 0";
+ case kFuncVarUniform:
+ return "func_uniform == 0";
+ case kFuncUniformRetVal:
+ return "func_uniform_retval() == 0";
+ case kUniformBuffer:
+ return "u == 0";
+ case kROStorageBuffer:
+ return "ro == 0";
+ case kFuncLetNonUniformRhs:
+ return "let_nonuniform_rhs == 0";
+ case kFuncVarNonUniform:
+ return "func_non_uniform == 0";
+ case kFuncNonUniformRetVal:
+ return "func_nonuniform_retval() == 0";
+ case kRWStorageBuffer:
+ return "rw == 0";
+ case kEndOfConditionRange:
+ return "<invalid>";
+ }
+ return "<invalid>";
+ }
+
+ /// Convert a function call to its string representation.
+ static std::string FunctionToStr(Function f) {
+ switch (f) {
+ case kUserNoRestriction:
+ return "user_no_restriction()";
+ case kMin:
+ return "min(1, 1)";
+ case kTextureSampleLevel:
+ return "textureSampleLevel(t, s, vec2(0.5, 0.5), 0.0)";
+ case kUserRequiredToBeUniform:
+ return "user_required_to_be_uniform()";
+ case kWorkgroupBarrier:
+ return "workgroupBarrier()";
+ case kStorageBarrier:
+ return "storageBarrier()";
+ case kTextureSample:
+ return "textureSample(t, s, vec2(0.5, 0.5))";
+ case kTextureSampleBias:
+ return "textureSampleBias(t, s, vec2(0.5, 0.5), 2.0)";
+ case kTextureSampleCompare:
+ return "textureSampleCompare(td, sc, vec2(0.5, 0.5), 0.5)";
+ case kDpdx:
+ return "dpdx(1.0)";
+ case kDpdxCoarse:
+ return "dpdxCoarse(1.0)";
+ case kDpdxFine:
+ return "dpdxFine(1.0)";
+ case kDpdy:
+ return "dpdy(1.0)";
+ case kDpdyCoarse:
+ return "dpdyCoarse(1.0)";
+ case kDpdyFine:
+ return "dpdyFine(1.0)";
+ case kFwidth:
+ return "fwidth(1.0)";
+ case kFwidthCoarse:
+ return "fwidthCoarse(1.0)";
+ case kFwidthFine:
+ return "fwidthFine(1.0)";
+ case kEndOfFunctionRange:
+ return "<invalid>";
+ }
+ return "<invalid>";
+ }
+
+ /// @returns true if `c` is a condition that may be non-uniform.
+ static bool MayBeNonUniform(Condition c) { return c > kLastUniformCondition; }
+
+ /// @returns true if `f` is a function call that is required to be uniform.
+ static bool RequiredToBeUniform(Function f) { return f > kLastNoRestrictionFunction; }
+
+ /// Convert a test parameter pair of condition+function to a string that can be used as part of
+ /// a test name.
+ static std::string ParamsToName(::testing::TestParamInfo<ParamType> params) {
+ Condition c = static_cast<Condition>(std::get<0>(params.param));
+ Function f = static_cast<Function>(std::get<1>(params.param));
+ std::string name;
+#define CASE(c) \
+ case c: \
+ name += #c; \
+ break
+
+ switch (c) {
+ CASE(kTrue);
+ CASE(kFalse);
+ CASE(kLiteral);
+ CASE(kModuleLet);
+ CASE(kPipelineOverridable);
+ CASE(kFuncLetUniformRhs);
+ CASE(kFuncVarUniform);
+ CASE(kFuncUniformRetVal);
+ CASE(kUniformBuffer);
+ CASE(kROStorageBuffer);
+ CASE(kFuncLetNonUniformRhs);
+ CASE(kFuncVarNonUniform);
+ CASE(kFuncNonUniformRetVal);
+ CASE(kRWStorageBuffer);
+ case kEndOfConditionRange:
+ break;
+ }
+ name += "_";
+ switch (f) {
+ CASE(kUserNoRestriction);
+ CASE(kMin);
+ CASE(kTextureSampleLevel);
+ CASE(kUserRequiredToBeUniform);
+ CASE(kWorkgroupBarrier);
+ CASE(kStorageBarrier);
+ CASE(kTextureSample);
+ CASE(kTextureSampleBias);
+ CASE(kTextureSampleCompare);
+ CASE(kDpdx);
+ CASE(kDpdxCoarse);
+ CASE(kDpdxFine);
+ CASE(kDpdy);
+ CASE(kDpdyCoarse);
+ CASE(kDpdyFine);
+ CASE(kFwidth);
+ CASE(kFwidthCoarse);
+ CASE(kFwidthFine);
+ case kEndOfFunctionRange:
+ break;
+ }
+#undef CASE
+
+ return name;
+ }
+};
+
+// Test the uniformity constraints for a function call inside a conditional statement.
+TEST_P(BasicTest, ConditionalFunctionCall) {
+ auto condition = static_cast<Condition>(std::get<0>(GetParam()));
+ auto function = static_cast<Function>(std::get<1>(GetParam()));
+ std::string src = R"(
+var<private> p : i32;
+var<workgroup> w : i32;
+@group(0) @binding(0) var<uniform> u : i32;
+@group(0) @binding(0) var<storage, read> ro : i32;
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+@group(1) @binding(0) var t : texture_2d<f32>;
+@group(1) @binding(1) var td : texture_depth_2d;
+@group(1) @binding(2) var s : sampler;
+@group(1) @binding(3) var sc : sampler_comparison;
+
+let module_let : i32 = 42;
+@id(42) override pipeline_overridable : i32;
+
+fn user_no_restriction() {}
+fn user_required_to_be_uniform() { workgroupBarrier(); }
+
+fn func_uniform_retval() -> i32 { return u; }
+fn func_nonuniform_retval() -> i32 { return rw; }
+
+fn foo() {
+ let let_uniform_rhs = 7;
+ let let_nonuniform_rhs = rw;
+
+ var func_uniform = 7;
+ var func_non_uniform = 7;
+ func_non_uniform = rw;
+
+ if ()" + ConditionToStr(condition) +
+ R"() {
+ )" + FunctionToStr(function) +
+ R"(;
+ }
+}
+)";
+
+ bool should_pass = !(MayBeNonUniform(condition) && RequiredToBeUniform(function));
+ RunTest(src, should_pass);
+ if (!should_pass) {
+ EXPECT_THAT(error_, ::testing::StartsWith("test:31:5 warning: "));
+ EXPECT_THAT(error_, ::testing::HasSubstr("must only be called from uniform control flow"));
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ UniformityAnalysisTest,
+ BasicTest,
+ ::testing::Combine(::testing::Range<int>(0, BasicTest::kEndOfConditionRange),
+ ::testing::Range<int>(0, BasicTest::kEndOfFunctionRange)),
+ BasicTest::ParamsToName);
+
+////////////////////////////////////////////////////////////////////////////////
+/// Test specific function and parameter tags that are not tested above.
+////////////////////////////////////////////////////////////////////////////////
+
+TEST_F(UniformityAnalysisTest, SubsequentControlFlowMayBeNonUniform_Pass) {
+ // Call a function that causes subsequent control flow to be non-uniform, and then call another
+ // function that doesn't require uniformity.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+var<private> p : i32;
+
+fn foo() {
+ if (rw == 0) {
+ p = 42;
+ return;
+ }
+ p = 5;
+ return;
+}
+
+fn bar() {
+ if (p == 42) {
+ p = 7;
+ }
+}
+
+fn main() {
+ foo();
+ bar();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, SubsequentControlFlowMayBeNonUniform_Fail) {
+ // Call a function that causes subsequent control flow to be non-uniform, and then call another
+ // function that requires uniformity.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+var<private> p : i32;
+
+fn foo() {
+ if (rw == 0) {
+ p = 42;
+ return;
+ }
+ p = 5;
+ return;
+}
+
+fn main() {
+ foo();
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:17:3 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:16:3 note: calling 'foo' may cause subsequent control flow to be non-uniform
+ foo();
+ ^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (rw == 0) {
+ ^^
+
+test:7:7 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ if (rw == 0) {
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, SubsequentControlFlowMayBeNonUniform_Nested_Fail) {
+ // Indirectly call a function that causes subsequent control flow to be non-uniform, and then
+ // call another function that requires uniformity.
+ // The lack of return statement in `foo()` requires that we implicitly add an edge from
+ // CF_return to that last control flow node of the function.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+var<private> p : i32;
+
+fn bar() {
+ if (rw == 0) {
+ p = 42;
+ return;
+ }
+ p = 5;
+ return;
+}
+
+fn foo() {
+ bar();
+}
+
+fn main() {
+ foo();
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:21:3 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:20:3 note: calling 'foo' may cause subsequent control flow to be non-uniform
+ foo();
+ ^^^
+
+test:16:3 note: calling 'bar' may cause subsequent control flow to be non-uniform
+ bar();
+ ^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (rw == 0) {
+ ^^
+
+test:7:7 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ if (rw == 0) {
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ParameterNoRestriction_Pass) {
+ // Pass a non-uniform value as an argument, and then try to use the return value for
+ // control-flow guarding a barrier.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+var<private> p : i32;
+
+fn foo(i : i32) -> i32 {
+ if (i == 0) {
+ // This assignment is non-uniform, but shouldn't affect the return value.
+ p = 42;
+ }
+ return 7;
+}
+
+fn bar() {
+ let x = foo(rw);
+ if (x == 7) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ParameterRequiredToBeUniform_Pass) {
+ // Pass a uniform value as an argument to a function that uses that parameter for control-flow
+ // guarding a barrier.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> ro : i32;
+
+fn foo(i : i32) {
+ if (i == 0) {
+ workgroupBarrier();
+ }
+}
+
+fn bar() {
+ foo(ro);
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ParameterRequiredToBeUniform_Fail) {
+ // Pass a non-uniform value as an argument to a function that uses that parameter for
+ // control-flow guarding a barrier.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo(i : i32) {
+ if (i == 0) {
+ workgroupBarrier();
+ }
+}
+
+fn bar() {
+ foo(rw);
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:11:7 warning: parameter 'i' of 'foo' must be uniform
+ foo(rw);
+ ^^
+
+test:6:5 note: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:11:7 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ foo(rw);
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ParameterRequiredToBeUniformForReturnValue_Pass) {
+ // Pass a uniform value as an argument to a function that uses that parameter to produce the
+ // return value, and then use the return value for control-flow guarding a barrier.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> ro : i32;
+
+fn foo(i : i32) -> i32 {
+ return 1 + i;
+}
+
+fn bar() {
+ if (foo(ro) == 7) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ParameterRequiredToBeUniformForReturnValue_Fail) {
+ // Pass a non-uniform value as an argument to a function that uses that parameter to produce the
+ // return value, and then use the return value for control-flow guarding a barrier.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo(i : i32) -> i32 {
+ return 1 + i;
+}
+
+fn bar() {
+ if (foo(rw) == 7) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:10:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:9:3 note: control flow depends on non-uniform value
+ if (foo(rw) == 7) {
+ ^^
+
+test:9:11 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ if (foo(rw) == 7) {
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ParameterRequiredToBeUniformForSubsequentControlFlow_Pass) {
+ // Pass a uniform value as an argument to a function that uses that parameter return early, and
+ // then invoke a barrier after calling that function.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> ro : i32;
+
+var<private> p : i32;
+
+fn foo(i : i32) {
+ if (i == 0) {
+ p = 42;
+ return;
+ }
+ p = 5;
+ return;
+}
+
+fn bar() {
+ foo(ro);
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ParameterRequiredToBeUniformForSubsequentControlFlow_Fail) {
+ // Pass a non-uniform value as an argument to a function that uses that parameter return early,
+ // and then invoke a barrier after calling that function.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+var<private> p : i32;
+
+fn foo(i : i32) {
+ if (i == 0) {
+ p = 42;
+ return;
+ }
+ p = 5;
+ return;
+}
+
+fn bar() {
+ foo(rw);
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:17:3 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:16:7 note: non-uniform function call argument causes subsequent control flow to be non-uniform
+ foo(rw);
+ ^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (i == 0) {
+ ^^
+
+test:7:7 note: reading from 'i' may result in a non-uniform value
+ if (i == 0) {
+ ^
+
+test:16:7 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ foo(rw);
+ ^^
+)");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Test shader IO attributes.
+////////////////////////////////////////////////////////////////////////////////
+
+struct BuiltinEntry {
+ std::string name;
+ std::string type;
+ bool uniform;
+ BuiltinEntry(std::string n, std::string t, bool u) : name(n), type(t), uniform(u) {}
+};
+
+class ComputeBuiltin : public UniformityAnalysisTestBase,
+ public ::testing::TestWithParam<BuiltinEntry> {};
+TEST_P(ComputeBuiltin, AsParam) {
+ std::string src = R"(
+@stage(compute) @workgroup_size(64)
+fn main(@builtin()" + GetParam().name +
+ R"() b : )" + GetParam().type + R"() {
+ if (all(vec3(b) == vec3(0u))) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ bool should_pass = GetParam().uniform;
+ RunTest(src, should_pass);
+ if (!should_pass) {
+ EXPECT_EQ(
+ error_,
+ R"(test:5:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:4:3 note: control flow depends on non-uniform value
+ if (all(vec3(b) == vec3(0u))) {
+ ^^
+
+test:4:16 note: reading from builtin 'b' may result in a non-uniform value
+ if (all(vec3(b) == vec3(0u))) {
+ ^
+)");
+ }
+}
+
+TEST_P(ComputeBuiltin, InStruct) {
+ std::string src = R"(
+struct S {
+ @builtin()" + GetParam().name +
+ R"() b : )" + GetParam().type + R"(
+}
+
+@stage(compute) @workgroup_size(64)
+fn main(s : S) {
+ if (all(vec3(s.b) == vec3(0u))) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ bool should_pass = GetParam().uniform;
+ RunTest(src, should_pass);
+ if (!should_pass) {
+ EXPECT_EQ(
+ error_,
+ R"(test:9:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (all(vec3(s.b) == vec3(0u))) {
+ ^^
+
+test:8:16 note: reading from 's' may result in a non-uniform value
+ if (all(vec3(s.b) == vec3(0u))) {
+ ^
+)");
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(UniformityAnalysisTest,
+ ComputeBuiltin,
+ ::testing::Values(BuiltinEntry{"local_invocation_id", "vec3<u32>", false},
+ BuiltinEntry{"local_invocation_index", "u32", false},
+ BuiltinEntry{"global_invocation_id", "vec3<u32>", false},
+ BuiltinEntry{"workgroup_id", "vec3<u32>", true},
+ BuiltinEntry{"num_workgroups", "vec3<u32>", true}),
+ [](const ::testing::TestParamInfo<ComputeBuiltin::ParamType>& p) {
+ return p.param.name;
+ });
+
+TEST_F(UniformityAnalysisTest, ComputeBuiltin_MixedAttributesInStruct) {
+ // Mix both non-uniform and uniform shader IO attributes in the same structure. Even accessing
+ // just uniform member causes non-uniformity in this case.
+ std::string src = R"(
+struct S {
+ @builtin(num_workgroups) num_groups : vec3<u32>,
+ @builtin(local_invocation_index) idx : u32,
+}
+
+@stage(compute) @workgroup_size(64)
+fn main(s : S) {
+ if (s.num_groups.x == 0u) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:10:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:9:3 note: control flow depends on non-uniform value
+ if (s.num_groups.x == 0u) {
+ ^^
+
+test:9:7 note: reading from 's' may result in a non-uniform value
+ if (s.num_groups.x == 0u) {
+ ^
+)");
+}
+
+class FragmentBuiltin : public UniformityAnalysisTestBase,
+ public ::testing::TestWithParam<BuiltinEntry> {};
+TEST_P(FragmentBuiltin, AsParam) {
+ std::string src = R"(
+@stage(fragment)
+fn main(@builtin()" + GetParam().name +
+ R"() b : )" + GetParam().type + R"() {
+ if (u32(vec4(b).x) == 0u) {
+ dpdx(0.5);
+ }
+}
+)";
+
+ bool should_pass = GetParam().uniform;
+ RunTest(src, should_pass);
+ if (!should_pass) {
+ EXPECT_EQ(error_,
+ R"(test:5:5 warning: 'dpdx' must only be called from uniform control flow
+ dpdx(0.5);
+ ^^^^
+
+test:4:3 note: control flow depends on non-uniform value
+ if (u32(vec4(b).x) == 0u) {
+ ^^
+
+test:4:16 note: reading from builtin 'b' may result in a non-uniform value
+ if (u32(vec4(b).x) == 0u) {
+ ^
+)");
+ }
+}
+
+TEST_P(FragmentBuiltin, InStruct) {
+ std::string src = R"(
+struct S {
+ @builtin()" + GetParam().name +
+ R"() b : )" + GetParam().type + R"(
+}
+
+@stage(fragment)
+fn main(s : S) {
+ if (u32(vec4(s.b).x) == 0u) {
+ dpdx(0.5);
+ }
+}
+)";
+
+ bool should_pass = GetParam().uniform;
+ RunTest(src, should_pass);
+ if (!should_pass) {
+ EXPECT_EQ(error_,
+ R"(test:9:5 warning: 'dpdx' must only be called from uniform control flow
+ dpdx(0.5);
+ ^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (u32(vec4(s.b).x) == 0u) {
+ ^^
+
+test:8:16 note: reading from 's' may result in a non-uniform value
+ if (u32(vec4(s.b).x) == 0u) {
+ ^
+)");
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(UniformityAnalysisTest,
+ FragmentBuiltin,
+ ::testing::Values(BuiltinEntry{"position", "vec4<f32>", false},
+ BuiltinEntry{"front_facing", "bool", false},
+ BuiltinEntry{"sample_index", "u32", false},
+ BuiltinEntry{"sample_mask", "u32", false}),
+ [](const ::testing::TestParamInfo<FragmentBuiltin::ParamType>& p) {
+ return p.param.name;
+ });
+
+TEST_F(UniformityAnalysisTest, FragmentLocation) {
+ std::string src = R"(
+@stage(fragment)
+fn main(@location(0) l : f32) {
+ if (l == 0.0) {
+ dpdx(0.5);
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:5:5 warning: 'dpdx' must only be called from uniform control flow
+ dpdx(0.5);
+ ^^^^
+
+test:4:3 note: control flow depends on non-uniform value
+ if (l == 0.0) {
+ ^^
+
+test:4:7 note: reading from user-defined input 'l' may result in a non-uniform value
+ if (l == 0.0) {
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, FragmentLocation_InStruct) {
+ std::string src = R"(
+struct S {
+ @location(0) l : f32
+}
+
+@stage(fragment)
+fn main(s : S) {
+ if (s.l == 0.0) {
+ dpdx(0.5);
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:5 warning: 'dpdx' must only be called from uniform control flow
+ dpdx(0.5);
+ ^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (s.l == 0.0) {
+ ^^
+
+test:8:7 note: reading from 's' may result in a non-uniform value
+ if (s.l == 0.0) {
+ ^
+)");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Test loop conditions and conditional break/continue statements.
+////////////////////////////////////////////////////////////////////////////////
+
+namespace LoopTest {
+
+enum ControlFlowInterrupt {
+ kBreak,
+ kContinue,
+ kReturn,
+ kDiscard,
+};
+enum Condition {
+ kNone,
+ kUniform,
+ kNonUniform,
+};
+
+using LoopTestParams = std::tuple<int, int>;
+
+static std::string ToStr(ControlFlowInterrupt interrupt) {
+ switch (interrupt) {
+ case kBreak:
+ return "break";
+ case kContinue:
+ return "continue";
+ case kReturn:
+ return "return";
+ case kDiscard:
+ return "discard";
+ }
+ return "";
+}
+
+static std::string ToStr(Condition condition) {
+ switch (condition) {
+ case kNone:
+ return "uncondtiional";
+ case kUniform:
+ return "uniform";
+ case kNonUniform:
+ return "nonuniform";
+ }
+ return "";
+}
+
+class LoopTest : public UniformityAnalysisTestBase,
+ public ::testing::TestWithParam<LoopTestParams> {
+ protected:
+ std::string MakeInterrupt(ControlFlowInterrupt interrupt, Condition condition) {
+ switch (condition) {
+ case kNone:
+ return ToStr(interrupt);
+ case kUniform:
+ return "if (uniform_var == 42) { " + ToStr(interrupt) + "; }";
+ case kNonUniform:
+ return "if (nonuniform_var == 42) { " + ToStr(interrupt) + "; }";
+ }
+ return "<invalid>";
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(UniformityAnalysisTest,
+ LoopTest,
+ ::testing::Combine(::testing::Range<int>(0, kDiscard + 1),
+ ::testing::Range<int>(0, kNonUniform + 1)),
+ [](const ::testing::TestParamInfo<LoopTestParams>& p) {
+ ControlFlowInterrupt interrupt =
+ static_cast<ControlFlowInterrupt>(std::get<0>(p.param));
+ auto condition = static_cast<Condition>(std::get<1>(p.param));
+ return ToStr(interrupt) + "_" + ToStr(condition);
+ });
+
+TEST_P(LoopTest, CallInBody_InterruptAfter) {
+ // Test control-flow interrupt in a loop after a function call that requires uniform control
+ // flow.
+ auto interrupt = static_cast<ControlFlowInterrupt>(std::get<0>(GetParam()));
+ auto condition = static_cast<Condition>(std::get<1>(GetParam()));
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> uniform_var : i32;
+@group(0) @binding(0) var<storage, read_write> nonuniform_var : i32;
+
+fn foo() {
+ loop {
+ // Pretend that this isn't an infinite loop, in case the interrupt is a
+ // continue statement.
+ if (false) {
+ break;
+ }
+
+ workgroupBarrier();
+ )" + MakeInterrupt(interrupt, condition) +
+ R"(;
+ }
+}
+)";
+
+ if (condition == kNonUniform) {
+ RunTest(src, false);
+ EXPECT_THAT(
+ error_,
+ ::testing::StartsWith(
+ R"(test:13:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();)"));
+ EXPECT_THAT(error_,
+ ::testing::HasSubstr("test:14:9 note: reading from read_write storage buffer "
+ "'nonuniform_var' may result in a non-uniform value"));
+ } else {
+ RunTest(src, true);
+ }
+}
+
+TEST_P(LoopTest, CallInBody_InterruptBefore) {
+ // Test control-flow interrupt in a loop before a function call that requires uniform control
+ // flow.
+ auto interrupt = static_cast<ControlFlowInterrupt>(std::get<0>(GetParam()));
+ auto condition = static_cast<Condition>(std::get<1>(GetParam()));
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> uniform_var : i32;
+@group(0) @binding(0) var<storage, read_write> nonuniform_var : i32;
+
+fn foo() {
+ loop {
+ // Pretend that this isn't an infinite loop, in case the interrupt is a
+ // continue statement.
+ if (false) {
+ break;
+ }
+
+ )" + MakeInterrupt(interrupt, condition) +
+ R"(;
+ workgroupBarrier();
+ }
+}
+)";
+
+ if (condition == kNonUniform) {
+ RunTest(src, false);
+
+ EXPECT_THAT(
+ error_,
+ ::testing::StartsWith(
+ R"(test:14:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();)"));
+ EXPECT_THAT(error_,
+ ::testing::HasSubstr("test:13:9 note: reading from read_write storage buffer "
+ "'nonuniform_var' may result in a non-uniform value"));
+ } else {
+ RunTest(src, true);
+ }
+}
+
+TEST_P(LoopTest, CallInContinuing_InterruptInBody) {
+ // Test control-flow interrupt in a loop with a function call that requires uniform control flow
+ // in the continuing statement.
+ auto interrupt = static_cast<ControlFlowInterrupt>(std::get<0>(GetParam()));
+ auto condition = static_cast<Condition>(std::get<1>(GetParam()));
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> uniform_var : i32;
+@group(0) @binding(0) var<storage, read_write> nonuniform_var : i32;
+
+fn foo() {
+ loop {
+ // Pretend that this isn't an infinite loop, in case the interrupt is a
+ // continue statement.
+ if (false) {
+ break;
+ }
+
+ )" + MakeInterrupt(interrupt, condition) +
+ R"(;
+ continuing {
+ workgroupBarrier();
+ }
+ }
+}
+)";
+
+ if (condition == kNonUniform) {
+ RunTest(src, false);
+ EXPECT_THAT(
+ error_,
+ ::testing::StartsWith(
+ R"(test:15:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();)"));
+ EXPECT_THAT(error_,
+ ::testing::HasSubstr("test:13:9 note: reading from read_write storage buffer "
+ "'nonuniform_var' may result in a non-uniform value"));
+ } else {
+ RunTest(src, true);
+ }
+}
+
+TEST_F(UniformityAnalysisTest, Loop_CallInBody_UniformBreakInContinuing) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> n : i32;
+
+fn foo() {
+ var i = 0;
+ loop {
+ workgroupBarrier();
+ continuing {
+ i = i + 1;
+ if (i == n) {
+ break;
+ }
+ }
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Loop_CallInBody_NonUniformBreakInContinuing) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn foo() {
+ var i = 0;
+ loop {
+ workgroupBarrier();
+ continuing {
+ i = i + 1;
+ if (i == n) {
+ break;
+ }
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:7:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:10:7 note: control flow depends on non-uniform value
+ if (i == n) {
+ ^^
+
+test:10:16 note: reading from read_write storage buffer 'n' may result in a non-uniform value
+ if (i == n) {
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Loop_CallInContinuing_UniformBreakInContinuing) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> n : i32;
+
+fn foo() {
+ var i = 0;
+ loop {
+ continuing {
+ workgroupBarrier();
+ i = i + 1;
+ if (i == n) {
+ break;
+ }
+ }
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Loop_CallInContinuing_NonUniformBreakInContinuing) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn foo() {
+ var i = 0;
+ loop {
+ continuing {
+ workgroupBarrier();
+ i = i + 1;
+ if (i == n) {
+ break;
+ }
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:10:7 note: control flow depends on non-uniform value
+ if (i == n) {
+ ^^
+
+test:10:16 note: reading from read_write storage buffer 'n' may result in a non-uniform value
+ if (i == n) {
+ ^
+)");
+}
+
+class LoopDeadCodeTest : public UniformityAnalysisTestBase, public ::testing::TestWithParam<int> {};
+
+INSTANTIATE_TEST_SUITE_P(UniformityAnalysisTest,
+ LoopDeadCodeTest,
+ ::testing::Range<int>(0, kDiscard + 1),
+ [](const ::testing::TestParamInfo<LoopDeadCodeTest::ParamType>& p) {
+ return ToStr(static_cast<ControlFlowInterrupt>(p.param));
+ });
+
+TEST_P(LoopDeadCodeTest, AfterInterrupt) {
+ // Dead code after a control-flow interrupt in a loop shouldn't cause uniformity errors.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn foo() {
+ loop {
+ )" + ToStr(static_cast<ControlFlowInterrupt>(GetParam())) +
+ R"(;
+ if (n == 42) {
+ workgroupBarrier();
+ }
+ continuing {
+ // Pretend that this isn't an infinite loop, in case the interrupt is a
+ // continue statement.
+ if (false) {
+ break;
+ }
+ }
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Loop_VarBecomesNonUniformInLoopAfterBarrier) {
+ // Use a variable for a conditional barrier in a loop, and then assign a non-uniform value to
+ // that variable later in that loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (v == 0) {
+ workgroupBarrier();
+ break;
+ }
+
+ v = non_uniform;
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:5 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:12:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Loop_VarBecomesNonUniformInLoopAfterBarrier_BreakAtEnd) {
+ // Use a variable for a conditional barrier in a loop, and then assign a non-uniform value to
+ // that variable later in that loop. End the loop with a break statement to prevent the
+ // non-uniform value from causing an issue.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (v == 0) {
+ workgroupBarrier();
+ }
+
+ v = non_uniform;
+ break;
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Loop_ConditionalAssignNonUniformWithBreak_BarrierInLoop) {
+ // In a conditional block, assign a non-uniform value and then break, then use a variable for a
+ // conditional barrier later in the loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (true) {
+ v = non_uniform;
+ break;
+ }
+ if (v == 0) {
+ workgroupBarrier();
+ }
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Loop_ConditionalAssignNonUniformWithConditionalBreak_BarrierInLoop) {
+ // In a conditional block, assign a non-uniform value and then conditionally break, then use a
+ // variable for a conditional barrier later in the loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (true) {
+ v = non_uniform;
+ if (true) {
+ break;
+ }
+ }
+ if (v == 0) {
+ workgroupBarrier();
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:14:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:5 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:8:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Loop_ConditionalAssignNonUniformWithBreak_BarrierAfterLoop) {
+ // In a conditional block, assign a non-uniform value and then break, then use a variable for a
+ // conditional barrier after the loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (true) {
+ v = non_uniform;
+ break;
+ }
+ v = 5;
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:15:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:14:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:8:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Loop_VarBecomesUniformBeforeSomeExits_BarrierAfterLoop) {
+ // Assign a non-uniform value, have two exit points only one of which assigns a uniform value,
+ // then use a variable for a conditional barrier after the loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (true) {
+ break;
+ }
+
+ v = non_uniform;
+
+ if (false) {
+ v = 6;
+ break;
+ }
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:20:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:19:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:11:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Loop_VarBecomesUniformBeforeAllExits_BarrierAfterLoop) {
+ // Assign a non-uniform value, have two exit points both of which assigns a uniform value,
+ // then use a variable for a conditional barrier after the loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (true) {
+ v = 5;
+ break;
+ }
+
+ v = non_uniform;
+
+ if (false) {
+ v = 6;
+ break;
+ }
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Loop_AssignNonUniformBeforeConditionalBreak_BarrierAfterLoop) {
+ // Assign a non-uniform value and then break in a conditional block, then use a variable for a
+ // conditional barrier after the loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ v = non_uniform;
+ if (true) {
+ if (false) {
+ v = 5;
+ } else {
+ break;
+ }
+ v = 5;
+ }
+ v = 5;
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:20:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:19:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:7:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Loop_VarBecomesNonUniformBeforeConditionalContinue_BarrierAtStart) {
+ // Use a variable for a conditional barrier in a loop, assign a non-uniform value to
+ // that variable later in that loop, then perform a conditional continue before assigning a
+ // uniform value to that variable.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (v == 0) {
+ workgroupBarrier();
+ break;
+ }
+
+ v = non_uniform;
+ if (true) {
+ continue;
+ }
+
+ v = 5;
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:5 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:12:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest,
+ Loop_VarBecomesUniformBeforeConditionalContinue_BarrierInContinuing) {
+ // Use a variable for a conditional barrier in the continuing statement of a loop, assign a
+ // non-uniform value to that variable later in that loop, then conditionally assign a uniform
+ // value before continuing.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ v = non_uniform;
+
+ if (false) {
+ v = 5;
+ continue;
+ }
+
+ continuing {
+ if (v == 0) {
+ workgroupBarrier();
+ }
+ if (true) {
+ break;
+ }
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:16:9 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:15:7 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:7:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Loop_VarBecomesNonUniformBeforeConditionalContinue) {
+ // Use a variable for a conditional barrier in a loop, assign a non-uniform value to
+ // that variable later in that loop, then perform a conditional continue before assigning a
+ // uniform value to that variable.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (v == 0) {
+ workgroupBarrier();
+ break;
+ }
+
+ v = non_uniform;
+ if (true) {
+ continue;
+ }
+
+ v = 5;
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:5 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:12:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Loop_VarBecomesNonUniformInNestedLoopWithBreak_BarrierInLoop) {
+ // Use a variable for a conditional barrier in a loop, then conditionally assign a non-uniform
+ // value to that variable followed by a break in a nested loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (v == 0) {
+ workgroupBarrier();
+ break;
+ }
+
+ loop {
+ if (true) {
+ v = non_uniform;
+ break;
+ }
+ v = 5;
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:5 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:14:13 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest,
+ Loop_VarBecomesNonUniformInNestedLoopWithBreak_BecomesUniformAgain_BarrierAfterLoop) {
+ // Conditionally assign a non-uniform value followed by a break in a nested loop, assign a
+ // uniform value in the outer loop, and then use a variable for a conditional barrier after the
+ // loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ loop {
+ if (false) {
+ break;
+ }
+
+ loop {
+ if (true) {
+ v = non_uniform;
+ break;
+ }
+ }
+ v = 5;
+ }
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Loop_NonUniformValueNeverReachesContinuing) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ loop {
+ var v = non_uniform;
+ return;
+
+ continuing {
+ if (v == 0) {
+ workgroupBarrier();
+ }
+ }
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Loop_NonUniformBreakInBody_Reconverge) {
+ // Loops reconverge at exit, so test that we can call workgroupBarrier() after a loop that
+ // contains a non-uniform conditional break.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn foo() {
+ var i = 0;
+ loop {
+ if (i == n) {
+ break;
+ }
+ i = i + 1;
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Loop_NonUniformFunctionInBody_Reconverge) {
+ // Loops reconverge at exit, so test that we can call workgroupBarrier() after a loop that
+ // contains a call to a function that causes non-uniform control flow.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn bar() {
+ if (n == 42) {
+ return;
+ } else {
+ return;
+ }
+}
+
+fn foo() {
+ loop {
+ bar();
+ break;
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Loop_NonUniformFunctionDiscard_NoReconvergence) {
+ // Loops should not reconverge after non-uniform discard statements.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn bar() {
+ if (n == 42) {
+ discard;
+ }
+}
+
+fn foo() {
+ loop {
+ bar();
+ break;
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:15:3 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:12:5 note: calling 'bar' may cause subsequent control flow to be non-uniform
+ bar();
+ ^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (n == 42) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'n' may result in a non-uniform value
+ if (n == 42) {
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_CallInside_UniformCondition) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> n : i32;
+
+fn foo() {
+ for (var i = 0; i < n; i = i + 1) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_CallInside_NonUniformCondition) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn foo() {
+ for (var i = 0; i < n; i = i + 1) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ for (var i = 0; i < n; i = i + 1) {
+ ^^^
+
+test:5:23 note: reading from read_write storage buffer 'n' may result in a non-uniform value
+ for (var i = 0; i < n; i = i + 1) {
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_CallInside_InitializerCausesNonUniformFlow) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn bar() -> i32 {
+ if (n == 42) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+fn foo() {
+ for (var i = bar(); i < 10; i = i + 1) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:14:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:16 note: calling 'bar' may cause subsequent control flow to be non-uniform
+ for (var i = bar(); i < 10; i = i + 1) {
+ ^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (n == 42) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'n' may result in a non-uniform value
+ if (n == 42) {
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_CallInside_ContinuingCausesNonUniformFlow) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn bar() -> i32 {
+ if (n == 42) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+fn foo() {
+ for (var i = 0; i < 10; i = i + bar()) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:14:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:35 note: calling 'bar' may cause subsequent control flow to be non-uniform
+ for (var i = 0; i < 10; i = i + bar()) {
+ ^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (n == 42) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'n' may result in a non-uniform value
+ if (n == 42) {
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_VarBecomesNonUniformInContinuing_BarrierInLoop) {
+ // Use a variable for a conditional barrier in a loop, and then assign a non-uniform value to
+ // that variable in the continuing statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ for (var i = 0; i < 10; v = non_uniform) {
+ if (v == 0) {
+ workgroupBarrier();
+ break;
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:5 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:6:31 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ for (var i = 0; i < 10; v = non_uniform) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_VarBecomesUniformInContinuing_BarrierInLoop) {
+ // Use a variable for a conditional barrier in a loop, and then assign a uniform value to that
+ // variable in the continuing statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ for (var i = 0; i < 10; v = 5) {
+ if (v == 0) {
+ workgroupBarrier();
+ break;
+ }
+
+ v = non_uniform;
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_VarBecomesNonUniformInContinuing_BarrierAfterLoop) {
+ // Use a variable for a conditional barrier after a loop, and assign a non-uniform value to
+ // that variable in the continuing statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ for (var i = 0; i < 10; v = non_uniform) {
+ v = 5;
+ }
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:10:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:9:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:6:31 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ for (var i = 0; i < 10; v = non_uniform) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_VarBecomesUniformInContinuing_BarrierAfterLoop) {
+ // Use a variable for a conditional barrier after a loop, and assign a uniform value to that
+ // variable in the continuing statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ for (var i = 0; i < 10; v = 5) {
+ v = non_uniform;
+ }
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_VarBecomesNonUniformInLoopAfterBarrier) {
+ // Use a variable for a conditional barrier in a loop, and then assign a non-uniform value to
+ // that variable later in that loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ for (var i = 0; i < 10; i++) {
+ if (v == 0) {
+ workgroupBarrier();
+ break;
+ }
+
+ v = non_uniform;
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:5 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:12:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_ConditionalAssignNonUniformWithBreak_BarrierInLoop) {
+ // In a conditional block, assign a non-uniform value and then break, then use a variable for a
+ // conditional barrier later in the loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ for (var i = 0; i < 10; i++) {
+ if (true) {
+ v = non_uniform;
+ break;
+ }
+ if (v == 0) {
+ workgroupBarrier();
+ }
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_ConditionalAssignNonUniformWithBreak_BarrierAfterLoop) {
+ // In a conditional block, assign a non-uniform value and then break, then use a variable for a
+ // conditional barrier after the loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ for (var i = 0; i < 10; i++) {
+ if (true) {
+ v = non_uniform;
+ break;
+ }
+ v = 5;
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:15:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:14:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:8:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_VarRemainsNonUniformAtLoopEnd_BarrierAfterLoop) {
+ // Assign a non-uniform value, assign a uniform value before all explicit break points but leave
+ // the value non-uniform at loop exit, then use a variable for a conditional barrier after the
+ // loop.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ for (var i = 0; i < 10; i++) {
+ if (true) {
+ v = 5;
+ break;
+ }
+
+ v = non_uniform;
+
+ if (true) {
+ v = 6;
+ break;
+ }
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:21:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:20:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:12:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest,
+ ForLoop_VarBecomesNonUniformBeforeConditionalContinue_BarrierAtStart) {
+ // Use a variable for a conditional barrier in a loop, assign a non-uniform value to
+ // that variable later in that loop, then perform a conditional continue before assigning a
+ // uniform value to that variable.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ for (var i = 0; i < 10; i++) {
+ if (v == 0) {
+ workgroupBarrier();
+ break;
+ }
+
+ v = non_uniform;
+ if (true) {
+ continue;
+ }
+
+ v = 5;
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:5 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:12:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_VarBecomesNonUniformBeforeConditionalContinue) {
+ // Use a variable for a conditional barrier in a loop, assign a non-uniform value to
+ // that variable later in that loop, then perform a conditional continue before assigning a
+ // uniform value to that variable.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ for (var i = 0; i < 10; i++) {
+ if (v == 0) {
+ workgroupBarrier();
+ break;
+ }
+
+ v = non_uniform;
+ if (true) {
+ continue;
+ }
+
+ v = 5;
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:5 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:12:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ForLoop_NonUniformCondition_Reconverge) {
+ // Loops reconverge at exit, so test that we can call workgroupBarrier() after a loop that has a
+ // non-uniform condition.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn foo() {
+ for (var i = 0; i < n; i = i + 1) {
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+} // namespace LoopTest
+
+////////////////////////////////////////////////////////////////////////////////
+/// If-else statement tests.
+////////////////////////////////////////////////////////////////////////////////
+
+TEST_F(UniformityAnalysisTest, IfElse_UniformCondition_BarrierInTrueBlock) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> uniform_global : i32;
+
+fn foo() {
+ if (uniform_global == 42) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_UniformCondition_BarrierInElseBlock) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> uniform_global : i32;
+
+fn foo() {
+ if (uniform_global == 42) {
+ } else {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_UniformCondition_BarrierInElseIfBlock) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> uniform_global : i32;
+
+fn foo() {
+ if (uniform_global == 42) {
+ } else if (true) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_NonUniformCondition_BarrierInTrueBlock) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ if (non_uniform == 42) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (non_uniform == 42) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ if (non_uniform == 42) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_NonUniformCondition_BarrierInElseBlock) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ if (non_uniform == 42) {
+ } else {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:7:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (non_uniform == 42) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ if (non_uniform == 42) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_ShortCircuitingCondition_NonUniformLHS_And) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+var<private> p : i32;
+
+fn main() {
+ if ((non_uniform_global == 42) && false) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:34 note: control flow depends on non-uniform value
+ if ((non_uniform_global == 42) && false) {
+ ^^
+
+test:7:8 note: reading from read_write storage buffer 'non_uniform_global' may result in a non-uniform value
+ if ((non_uniform_global == 42) && false) {
+ ^^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_ShortCircuitingCondition_NonUniformRHS_And) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+var<private> p : i32;
+
+fn main() {
+ if (false && (non_uniform_global == 42)) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (false && (non_uniform_global == 42)) {
+ ^^
+
+test:7:17 note: reading from read_write storage buffer 'non_uniform_global' may result in a non-uniform value
+ if (false && (non_uniform_global == 42)) {
+ ^^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_ShortCircuitingCondition_NonUniformLHS_Or) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+var<private> p : i32;
+
+fn main() {
+ if ((non_uniform_global == 42) || true) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:34 note: control flow depends on non-uniform value
+ if ((non_uniform_global == 42) || true) {
+ ^^
+
+test:7:8 note: reading from read_write storage buffer 'non_uniform_global' may result in a non-uniform value
+ if ((non_uniform_global == 42) || true) {
+ ^^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_ShortCircuitingCondition_NonUniformRHS_Or) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+var<private> p : i32;
+
+fn main() {
+ if (true || (non_uniform_global == 42)) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (true || (non_uniform_global == 42)) {
+ ^^
+
+test:7:16 note: reading from read_write storage buffer 'non_uniform_global' may result in a non-uniform value
+ if (true || (non_uniform_global == 42)) {
+ ^^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_NonUniformCondition_BarrierInElseIfBlock) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ if (non_uniform == 42) {
+ } else if (true) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:7:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (non_uniform == 42) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ if (non_uniform == 42) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_VarBecomesNonUniform_BeforeCondition) {
+ // Use a function-scope variable for control-flow guarding a barrier, and then assign to that
+ // variable before checking the condition.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var v = 0;
+ v = rw;
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:6:7 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ v = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_VarBecomesNonUniform_AfterCondition) {
+ // Use a function-scope variable for control-flow guarding a barrier, and then assign to that
+ // variable after checking the condition.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var v = 0;
+ if (v == 0) {
+ v = rw;
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_VarBecomesNonUniformInIf_BarrierInElse) {
+ // Assign a non-uniform value to a variable in an if-block, and then use that variable for a
+ // conditional barrier in the else block.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ if (true) {
+ v = non_uniform;
+ } else {
+ if (v == 0) {
+ workgroupBarrier();
+ }
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_AssignNonUniformInIf_AssignUniformInElse) {
+ // Assign a non-uniform value to a variable in an if-block and a uniform value in the else
+ // block, and then use that variable for a conditional barrier after the if-else statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ if (true) {
+ if (true) {
+ v = non_uniform;
+ } else {
+ v = 5;
+ }
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:15:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:14:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:8:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_AssignNonUniformInIfWithReturn) {
+ // Assign a non-uniform value to a variable in an if-block followed by a return, and then use
+ // that variable for a conditional barrier after the if-else statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ if (true) {
+ v = non_uniform;
+ return;
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_AssignNonUniformBeforeIf_BothBranchesAssignUniform) {
+ // Assign a non-uniform value to a variable before and if-else statement, assign uniform values
+ // in both branch of the if-else, and then use that variable for a conditional barrier after
+ // the if-else statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ v = non_uniform;
+ if (true) {
+ v = 5;
+ } else {
+ v = 6;
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_AssignNonUniformBeforeIf_OnlyTrueBranchAssignsUniform) {
+ // Assign a non-uniform value to a variable before and if-else statement, assign a uniform value
+ // in the true branch of the if-else, and then use that variable for a conditional barrier after
+ // the if-else statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ v = non_uniform;
+ if (true) {
+ v = 5;
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:12:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:11:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:6:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_AssignNonUniformBeforeIf_OnlyFalseBranchAssignsUniform) {
+ // Assign a non-uniform value to a variable before and if-else statement, assign a uniform value
+ // in the false branch of the if-else, and then use that variable for a conditional barrier
+ // after the if-else statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ v = non_uniform;
+ if (true) {
+ } else {
+ v = 5;
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:13:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:12:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:6:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest,
+ IfElse_AssignNonUniformBeforeIf_OnlyTrueBranchAssignsUniform_FalseBranchReturns) {
+ // Assign a non-uniform value to a variable before and if-else statement, assign a uniform value
+ // in the true branch of the if-else, leave the variable untouched in the false branch and just
+ // return, and then use that variable for a conditional barrier after the if-else statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ v = non_uniform;
+ if (true) {
+ v = 5;
+ } else {
+ return;
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest,
+ IfElse_AssignNonUniformBeforeIf_OnlyFalseBranchAssignsUniform_TrueBranchReturns) {
+ // Assign a non-uniform value to a variable before and if-else statement, assign a uniform value
+ // in the false branch of the if-else, leave the variable untouched in the true branch and just
+ // return, and then use that variable for a conditional barrier after the if-else statement.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ v = non_uniform;
+ if (true) {
+ return;
+ } else {
+ v = 5;
+ }
+
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_NonUniformCondition_Reconverge) {
+ // If statements reconverge at exit, so test that we can call workgroupBarrier() after an if
+ // statement with a non-uniform condition.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ if (non_uniform == 42) {
+ } else {
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_ShortCircuitingNonUniformConditionLHS_Reconverge) {
+ // If statements reconverge at exit, so test that we can call workgroupBarrier() after an if
+ // statement with a non-uniform condition that uses short-circuiting.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ if (non_uniform == 42 || true) {
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_ShortCircuitingNonUniformConditionRHS_Reconverge) {
+ // If statements reconverge at exit, so test that we can call workgroupBarrier() after an if
+ // statement with a non-uniform condition that uses short-circuiting.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ if (false && non_uniform == 42) {
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_NonUniformFunctionCall_Reconverge) {
+ // If statements reconverge at exit, so test that we can call workgroupBarrier() after an if
+ // statement with a non-uniform condition.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar() {
+ if (non_uniform == 42) {
+ return;
+ } else {
+ return;
+ }
+}
+
+fn foo() {
+ if (non_uniform == 42) {
+ bar();
+ } else {
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_NonUniformReturn_NoReconverge) {
+ // If statements should not reconverge after non-uniform returns.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ if (non_uniform == 42) {
+ return;
+ } else {
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:3 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (non_uniform == 42) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ if (non_uniform == 42) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, IfElse_NonUniformDiscard_NoReconverge) {
+ // If statements should not reconverge after non-uniform discards.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ if (non_uniform == 42) {
+ discard;
+ } else {
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:3 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (non_uniform == 42) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ if (non_uniform == 42) {
+ ^^^^^^^^^^^
+)");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Switch statement tests.
+////////////////////////////////////////////////////////////////////////////////
+
+TEST_F(UniformityAnalysisTest, Switch_NonUniformCondition_BarrierInCase) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ switch (non_uniform) {
+ case 42: {
+ workgroupBarrier();
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:7:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ switch (non_uniform) {
+ ^^^^^^
+
+test:5:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ switch (non_uniform) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Switch_NonUniformCondition_BarrierInDefault) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ switch (non_uniform) {
+ default: {
+ workgroupBarrier();
+ break;
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:7:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ switch (non_uniform) {
+ ^^^^^^
+
+test:5:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ switch (non_uniform) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Switch_NonUniformBreak) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ switch (condition) {
+ case 42: {
+ if (non_uniform == 42) {
+ break;
+ }
+ workgroupBarrier();
+ }
+ default: {
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:11:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:7 note: control flow depends on non-uniform value
+ if (non_uniform == 42) {
+ ^^
+
+test:8:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ if (non_uniform == 42) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Switch_NonUniformBreakInDifferentCase) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ switch (condition) {
+ case 0: {
+ if (non_uniform == 42) {
+ break;
+ }
+ }
+ case 42: {
+ workgroupBarrier();
+ }
+ default: {
+ }
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Switch_NonUniformBreakInDifferentCase_Fallthrough) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ switch (condition) {
+ case 0: {
+ if (non_uniform == 42) {
+ break;
+ }
+ fallthrough;
+ }
+ case 42: {
+ workgroupBarrier();
+ }
+ default: {
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:14:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:7 note: control flow depends on non-uniform value
+ if (non_uniform == 42) {
+ ^^
+
+test:8:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ if (non_uniform == 42) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Switch_VarBecomesNonUniformInDifferentCase_WithBreak) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = 0;
+ switch (condition) {
+ case 0: {
+ x = non_uniform;
+ break;
+ }
+ case 42: {
+ if (x == 0) {
+ workgroupBarrier();
+ }
+ }
+ default: {
+ }
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Switch_VarBecomesNonUniformInDifferentCase_WithFallthrough) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = 0;
+ switch (condition) {
+ case 0: {
+ x = non_uniform;
+ fallthrough;
+ }
+ case 42: {
+ if (x == 0) {
+ workgroupBarrier();
+ }
+ }
+ default: {
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:14:9 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:7 note: control flow depends on non-uniform value
+ if (x == 0) {
+ ^^
+
+test:9:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ x = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Switch_VarBecomesUniformInDifferentCase_WithBreak) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = non_uniform;
+ switch (condition) {
+ case 0: {
+ x = 5;
+ break;
+ }
+ case 42: {
+ if (x == 0) {
+ workgroupBarrier();
+ }
+ }
+ default: {
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:14:9 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:7 note: control flow depends on non-uniform value
+ if (x == 0) {
+ ^^
+
+test:6:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var x = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Switch_VarBecomesUniformInDifferentCase_WithFallthrough) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = non_uniform;
+ switch (condition) {
+ case 0: {
+ x = 5;
+ fallthrough;
+ }
+ case 42: {
+ if (x == 0) {
+ workgroupBarrier();
+ }
+ }
+ default: {
+ }
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Switch_VarBecomesNonUniformInCase_BarrierAfter) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = 0;
+ switch (condition) {
+ case 0: {
+ x = non_uniform;
+ }
+ case 42: {
+ x = 5;
+ }
+ default: {
+ x = 6;
+ }
+ }
+ if (x == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:19:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:18:3 note: control flow depends on non-uniform value
+ if (x == 0) {
+ ^^
+
+test:9:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ x = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Switch_VarBecomesUniformInAllCases_BarrierAfter) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = non_uniform;
+ switch (condition) {
+ case 0: {
+ x = 4;
+ }
+ case 42: {
+ x = 5;
+ }
+ default: {
+ x = 6;
+ }
+ }
+ if (x == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Switch_VarBecomesUniformInSomeCases_BarrierAfter) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = non_uniform;
+ switch (condition) {
+ case 0: {
+ x = 4;
+ }
+ case 42: {
+ }
+ default: {
+ x = 6;
+ }
+ }
+ if (x == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:18:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:17:3 note: control flow depends on non-uniform value
+ if (x == 0) {
+ ^^
+
+test:6:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var x = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Switch_VarBecomesUniformInCasesThatDontReturn_BarrierAfter) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = non_uniform;
+ switch (condition) {
+ case 0: {
+ x = 4;
+ }
+ case 42: {
+ return;
+ }
+ default: {
+ x = 6;
+ }
+ }
+ if (x == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Switch_VarBecomesUniformAfterConditionalBreak_BarrierAfter) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = non_uniform;
+ switch (condition) {
+ case 0: {
+ x = 4;
+ }
+ case 42: {
+ }
+ default: {
+ if (false) {
+ break;
+ }
+ x = 6;
+ }
+ }
+ if (x == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:21:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:20:3 note: control flow depends on non-uniform value
+ if (x == 0) {
+ ^^
+
+test:6:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var x = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Switch_NestedInLoop_VarBecomesNonUniformWithBreak_BarrierInLoop) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = 0;
+ loop {
+ if (x == 0) {
+ workgroupBarrier();
+ break;
+ }
+
+ switch (condition) {
+ case 0: {
+ x = non_uniform;
+ break;
+ }
+ default: {
+ x = 6;
+ }
+ }
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:5 note: control flow depends on non-uniform value
+ if (x == 0) {
+ ^^
+
+test:15:13 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ x = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Switch_NestedInLoop_VarBecomesNonUniformWithBreak_BarrierAfterLoop) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(0) var<uniform> condition : i32;
+
+fn foo() {
+ var x = 0;
+ loop {
+ if (false) {
+ break;
+ }
+ switch (condition) {
+ case 0: {
+ x = non_uniform;
+ break;
+ }
+ default: {
+ x = 6;
+ }
+ }
+ x = 5;
+ }
+ if (x == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Switch_NonUniformCondition_Reconverge) {
+ // Switch statements reconverge at exit, so test that we can call workgroupBarrier() after a
+ // switch statement that contains a non-uniform conditional break.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ switch (non_uniform) {
+ default: {
+ break;
+ }
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Switch_NonUniformBreak_Reconverge) {
+ // Switch statements reconverge at exit, so test that we can call workgroupBarrier() after a
+ // switch statement that contains a non-uniform conditional break.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ switch (42) {
+ default: {
+ if (non_uniform == 0) {
+ break;
+ }
+ break;
+ }
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Switch_NonUniformFunctionCall_Reconverge) {
+ // Switch statements reconverge at exit, so test that we can call workgroupBarrier() after a
+ // switch statement that contains a call to a function that causes non-uniform control flow.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn bar() {
+ if (n == 42) {
+ return;
+ } else {
+ return;
+ }
+}
+
+fn foo() {
+ switch (42) {
+ default: {
+ bar();
+ break;
+ }
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, Switch_NonUniformFunctionDiscard_NoReconvergence) {
+ // Switch statements should not reconverge after non-uniform discards.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> n : i32;
+
+fn bar() {
+ if (n == 42) {
+ discard;
+ }
+}
+
+fn foo() {
+ switch (42) {
+ default: {
+ bar();
+ break;
+ }
+ }
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:17:3 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:7 note: calling 'bar' may cause subsequent control flow to be non-uniform
+ bar();
+ ^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (n == 42) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'n' may result in a non-uniform value
+ if (n == 42) {
+ ^
+)");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Pointer tests.
+////////////////////////////////////////////////////////////////////////////////
+
+TEST_F(UniformityAnalysisTest, AssignNonUniformThroughPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ *&v = non_uniform;
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:6:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ *&v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, AssignNonUniformThroughCapturedPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ let pv = &v;
+ *pv = non_uniform;
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:7:9 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ *pv = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, AssignUniformThroughPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = non_uniform;
+ *&v = 42;
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, AssignUniformThroughCapturedPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = non_uniform;
+ let pv = &v;
+ *pv = 42;
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, AssignUniformThroughCapturedPointer_InNonUniformControlFlow) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ let pv = &v;
+ if (non_uniform == 0) {
+ *pv = 42;
+ }
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:11:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (non_uniform == 0) {
+ ^^
+
+test:7:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ if (non_uniform == 0) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, LoadNonUniformThroughPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = non_uniform;
+ if (*&v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:7:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:6:3 note: control flow depends on non-uniform value
+ if (*&v == 0) {
+ ^^
+
+test:5:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, LoadNonUniformThroughCapturedPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = non_uniform;
+ let pv = &v;
+ if (*pv == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (*pv == 0) {
+ ^^
+
+test:5:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, LoadNonUniformThroughPointerParameter) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>) {
+ if (*p == 0) {
+ workgroupBarrier();
+ }
+}
+
+fn foo() {
+ var v = non_uniform;
+ bar(&v);
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:12:7 warning: parameter 'p' of 'bar' must be uniform
+ bar(&v);
+ ^
+
+test:6:5 note: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:11:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, LoadUniformThroughPointer) {
+ std::string src = R"(
+fn foo() {
+ var v = 42;
+ if (*&v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, LoadUniformThroughCapturedPointer) {
+ std::string src = R"(
+fn foo() {
+ var v = 42;
+ let pv = &v;
+ if (*pv == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, LoadUniformThroughPointerParameter) {
+ std::string src = R"(
+fn bar(p : ptr<function, i32>) {
+ if (*p == 0) {
+ workgroupBarrier();
+ }
+}
+
+fn foo() {
+ var v = 42;
+ bar(&v);
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, StoreNonUniformAfterCapturingPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ let pv = &v;
+ v = non_uniform;
+ if (*pv == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (*pv == 0) {
+ ^^
+
+test:7:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, StoreUniformAfterCapturingPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = non_uniform;
+ let pv = &v;
+ v = 42;
+ if (*pv == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, AssignNonUniformThroughLongChainOfPointers) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ let pv1 = &*&v;
+ let pv2 = &*&*pv1;
+ *&*&*pv2 = non_uniform;
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:10:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:9:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:8:14 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ *&*&*pv2 = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, LoadNonUniformThroughLongChainOfPointers) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = non_uniform;
+ let pv1 = &*&v;
+ let pv2 = &*&*pv1;
+ if (*&*&*pv2 == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (*&*&*pv2 == 0) {
+ ^^
+
+test:5:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, AssignUniformThenNonUniformThroughDifferentPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ let pv1 = &v;
+ let pv2 = &v;
+ *pv1 = 42;
+ *pv2 = non_uniform;
+ if (*pv1 == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:11:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:10:3 note: control flow depends on non-uniform value
+ if (*pv1 == 0) {
+ ^^
+
+test:9:10 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ *pv2 = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, AssignNonUniformThenUniformThroughDifferentPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ var v = 0;
+ let pv1 = &v;
+ let pv2 = &v;
+ *pv1 = non_uniform;
+ *pv2 = 42;
+ if (*pv1 == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, UnmodifiedPointerParameterNonUniform) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>) {
+}
+
+fn foo() {
+ var v = non_uniform;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:11:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:10:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:8:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, UnmodifiedPointerParameterUniform) {
+ std::string src = R"(
+fn bar(p : ptr<function, i32>) {
+}
+
+fn foo() {
+ var v = 42;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, AssignNonUniformThroughPointerInFunctionCall) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>) {
+ *p = non_uniform;
+}
+
+fn foo() {
+ var v = 0;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:12:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:11:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:10:7 note: pointer contents may become non-uniform after calling 'bar'
+ bar(&v);
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, AssignUniformThroughPointerInFunctionCall) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>) {
+ *p = 42;
+}
+
+fn foo() {
+ var v = non_uniform;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, AssignNonUniformThroughPointerInFunctionCallViaArg) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>, a : i32) {
+ *p = a;
+}
+
+fn foo() {
+ var v = 0;
+ bar(&v, non_uniform);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:12:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:11:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:10:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ bar(&v, non_uniform);
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, AssignNonUniformThroughPointerInFunctionCallViaPointerArg) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>, a : ptr<function, i32>) {
+ *p = *a;
+}
+
+fn foo() {
+ var v = 0;
+ var a = non_uniform;
+ bar(&v, &a);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:13:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:12:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:10:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var a = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, AssignUniformThroughPointerInFunctionCallViaArg) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>, a : i32) {
+ *p = a;
+}
+
+fn foo() {
+ var v = non_uniform;
+ bar(&v, 42);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, AssignUniformThroughPointerInFunctionCallViaPointerArg) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>, a : ptr<function, i32>) {
+ *p = *a;
+}
+
+fn foo() {
+ var v = non_uniform;
+ var a = 42;
+ bar(&v, &a);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, AssignNonUniformThroughPointerInFunctionCallChain) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn f3(p : ptr<function, i32>, a : ptr<function, i32>) {
+ *p = *a;
+}
+
+fn f2(p : ptr<function, i32>, a : ptr<function, i32>) {
+ f3(p, a);
+}
+
+fn f1(p : ptr<function, i32>, a : ptr<function, i32>) {
+ f2(p, a);
+}
+
+fn foo() {
+ var v = 0;
+ var a = non_uniform;
+ f1(&v, &a);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:21:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:20:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:18:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var a = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, AssignUniformThroughPointerInFunctionCallChain) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn f3(p : ptr<function, i32>, a : ptr<function, i32>) {
+ *p = *a;
+}
+
+fn f2(p : ptr<function, i32>, a : ptr<function, i32>) {
+ f3(p, a);
+}
+
+fn f1(p : ptr<function, i32>, a : ptr<function, i32>) {
+ f2(p, a);
+}
+
+fn foo() {
+ var v = non_uniform;
+ var a = 42;
+ f1(&v, &a);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, MakePointerParamUniformInReturnExpression) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn zoo(p : ptr<function, i32>) -> i32 {
+ *p = 5;
+ return 6;
+}
+
+fn bar(p : ptr<function, i32>) -> i32 {
+ *p = non_uniform;
+ return zoo(p);
+}
+
+fn foo() {
+ var v = 0;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, MakePointerParamNonUniformInReturnExpression) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn zoo(p : ptr<function, i32>) -> i32 {
+ *p = non_uniform;
+ return 6;
+}
+
+fn bar(p : ptr<function, i32>) -> i32 {
+ *p = 5;
+ return zoo(p);
+}
+
+fn foo() {
+ var v = 0;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:18:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:17:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:16:7 note: pointer contents may become non-uniform after calling 'bar'
+ bar(&v);
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, PointerParamAssignNonUniformInTrueAndUniformInFalse) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>) {
+ if (true) {
+ *p = non_uniform;
+ } else {
+ *p = 5;
+ }
+}
+
+fn foo() {
+ var v = 0;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:16:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:15:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:14:7 note: pointer contents may become non-uniform after calling 'bar'
+ bar(&v);
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ConditionalAssignNonUniformToPointerParamAndReturn) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>) {
+ if (true) {
+ *p = non_uniform;
+ return;
+ }
+ *p = 5;
+}
+
+fn foo() {
+ var v = 0;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:16:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:15:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:14:7 note: pointer contents may become non-uniform after calling 'bar'
+ bar(&v);
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ConditionalAssignNonUniformToPointerParamAndBreakFromSwitch) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+@group(0) @binding(1) var<uniform> condition : i32;
+
+fn bar(p : ptr<function, i32>) {
+ switch (condition) {
+ case 0 {
+ if (true) {
+ *p = non_uniform;
+ break;
+ }
+ *p = 5;
+ }
+ default {
+ *p = 6;
+ }
+ }
+}
+
+fn foo() {
+ var v = 0;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:24:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:23:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:22:7 note: pointer contents may become non-uniform after calling 'bar'
+ bar(&v);
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ConditionalAssignNonUniformToPointerParamAndBreakFromLoop) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>) {
+ loop {
+ if (true) {
+ *p = non_uniform;
+ break;
+ }
+ *p = 5;
+ }
+}
+
+fn foo() {
+ var v = 0;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:18:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:17:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:16:7 note: pointer contents may become non-uniform after calling 'bar'
+ bar(&v);
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ConditionalAssignNonUniformToPointerParamAndContinue) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo(p : ptr<function, i32>) {
+ loop {
+ if (*p == 0) {
+ workgroupBarrier();
+ break;
+ }
+
+ if (true) {
+ *p = non_uniform;
+ continue;
+ }
+ *p = 5;
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:7:7 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:6:5 note: control flow depends on non-uniform value
+ if (*p == 0) {
+ ^^
+
+test:12:12 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ *p = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, PointerParamMaybeBecomesUniform) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>) {
+ if (true) {
+ *p = 5;
+ return;
+ }
+}
+
+fn foo() {
+ var v = non_uniform;
+ bar(&v);
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:15:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:14:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:12:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, NonUniformPointerParameterBecomesUniform_AfterUse) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(a : ptr<function, i32>, b : ptr<function, i32>) {
+ *b = *a;
+ *a = 0;
+}
+
+fn foo() {
+ var a = non_uniform;
+ var b = 0;
+ bar(&a, &b);
+ if (b == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:14:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:3 note: control flow depends on non-uniform value
+ if (b == 0) {
+ ^^
+
+test:10:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var a = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, NonUniformPointerParameterBecomesUniform_BeforeUse) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(a : ptr<function, i32>, b : ptr<function, i32>) {
+ *a = 0;
+ *b = *a;
+}
+
+fn foo() {
+ var a = non_uniform;
+ var b = 0;
+ bar(&a, &b);
+ if (b == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, UniformPointerParameterBecomesNonUniform_BeforeUse) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(a : ptr<function, i32>, b : ptr<function, i32>) {
+ *a = non_uniform;
+ *b = *a;
+}
+
+fn foo() {
+ var a = 0;
+ var b = 0;
+ bar(&a, &b);
+ if (b == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:14:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:3 note: control flow depends on non-uniform value
+ if (b == 0) {
+ ^^
+
+test:12:11 note: pointer contents may become non-uniform after calling 'bar'
+ bar(&a, &b);
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, UniformPointerParameterBecomesNonUniform_AfterUse) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(a : ptr<function, i32>, b : ptr<function, i32>) {
+ *b = *a;
+ *a = non_uniform;
+}
+
+fn foo() {
+ var a = 0;
+ var b = 0;
+ bar(&a, &b);
+ if (b == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, NonUniformPointerParameterUpdatedInPlace) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(p : ptr<function, i32>) {
+ (*p)++;
+}
+
+fn foo() {
+ var v = non_uniform;
+ bar(&v);
+ if (v == 1) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:12:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:11:3 note: control flow depends on non-uniform value
+ if (v == 1) {
+ ^^
+
+test:9:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var v = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, MultiplePointerParametersBecomeNonUniform) {
+ // The analysis traverses the tree for each pointer parameter, and we need to make sure that we
+ // reset the "visited" state of nodes in between these traversals to properly capture each of
+ // their uniformity states.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(a : ptr<function, i32>, b : ptr<function, i32>) {
+ *a = non_uniform;
+ *b = non_uniform;
+}
+
+fn foo() {
+ var a = 0;
+ var b = 0;
+ bar(&a, &b);
+ if (b == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:14:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:3 note: control flow depends on non-uniform value
+ if (b == 0) {
+ ^^
+
+test:12:11 note: pointer contents may become non-uniform after calling 'bar'
+ bar(&a, &b);
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, MultiplePointerParametersWithEdgesToEachOther) {
+ // The analysis traverses the tree for each pointer parameter, and we need to make sure that we
+ // reset the "visited" state of nodes in between these traversals to properly capture each of
+ // their uniformity states.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn bar(a : ptr<function, i32>, b : ptr<function, i32>, c : ptr<function, i32>) {
+ *a = *a;
+ *b = *b;
+ *c = *a + *b;
+}
+
+fn foo() {
+ var a = non_uniform;
+ var b = 0;
+ var c = 0;
+ bar(&a, &b, &c);
+ if (c == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:16:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:15:3 note: control flow depends on non-uniform value
+ if (c == 0) {
+ ^^
+
+test:11:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ var a = non_uniform;
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, MaximumNumberOfPointerParameters) {
+ // Create a function with the maximum number of parameters, all pointers, to stress the
+ // quadratic nature of the analysis.
+ ProgramBuilder b;
+ auto& ty = b.ty;
+
+ // fn foo(p0 : ptr<function, i32>, p1 : ptr<function, i32>, ...) {
+ // let rhs = *p0 + *p1 + ... + *p244;
+ // *p1 = rhs;
+ // *p2 = rhs;
+ // ...
+ // *p254 = rhs;
+ // }
+ ast::VariableList params;
+ ast::StatementList foo_body;
+ const ast::Expression* rhs_init = b.Deref("p0");
+ for (int i = 1; i < 255; i++) {
+ rhs_init = b.Add(rhs_init, b.Deref("p" + std::to_string(i)));
+ }
+ foo_body.push_back(b.Decl(b.Let("rhs", nullptr, rhs_init)));
+ for (int i = 0; i < 255; i++) {
+ params.push_back(
+ b.Param("p" + std::to_string(i), ty.pointer(ty.i32(), ast::StorageClass::kFunction)));
+ if (i > 0) {
+ foo_body.push_back(b.Assign(b.Deref("p" + std::to_string(i)), "rhs"));
+ }
+ }
+ b.Func("foo", std::move(params), ty.void_(), foo_body);
+
+ // var<private> non_uniform_global : i32;
+ // fn main() {
+ // var v0 : i32;
+ // var v1 : i32;
+ // ...
+ // var v254 : i32;
+ // v0 = non_uniform_global;
+ // foo(&v0, &v1, ..., &v254);
+ // if (v254 == 0) {
+ // workgroupBarrier();
+ // }
+ // }
+ b.Global("non_uniform_global", ty.i32(), ast::StorageClass::kPrivate);
+ ast::StatementList main_body;
+ ast::ExpressionList args;
+ for (int i = 0; i < 255; i++) {
+ auto name = "v" + std::to_string(i);
+ main_body.push_back(b.Decl(b.Var(name, ty.i32())));
+ args.push_back(b.AddressOf(name));
+ }
+ main_body.push_back(b.Assign("v0", "non_uniform_global"));
+ main_body.push_back(b.CallStmt(b.create<ast::CallExpression>(b.Expr("foo"), args)));
+ main_body.push_back(
+ b.If(b.Equal("v254", 0_i), b.Block(b.CallStmt(b.Call("workgroupBarrier")))));
+ b.Func("main", {}, ty.void_(), main_body);
+
+ // TODO(jrprice): Expect false when uniformity issues become errors.
+ EXPECT_TRUE(RunTest(std::move(b))) << error_;
+ EXPECT_EQ(error_,
+ R"(warning: 'workgroupBarrier' must only be called from uniform control flow
+note: control flow depends on non-uniform value
+note: reading from module-scope private variable 'non_uniform_global' may result in a non-uniform value)");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Tests to cover access to aggregate types.
+////////////////////////////////////////////////////////////////////////////////
+
+TEST_F(UniformityAnalysisTest, VectorElement_Uniform) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> v : vec4<i32>;
+
+fn foo() {
+ if (v[2] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, VectorElement_NonUniform) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> v : array<i32>;
+
+fn foo() {
+ if (v[2] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (v[2] == 0) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'v' may result in a non-uniform value
+ if (v[2] == 0) {
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, VectorElement_BecomesNonUniform_BeforeCondition) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var v : vec4<i32>;
+ v[2] = rw;
+ if (v[2] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (v[2] == 0) {
+ ^^
+
+test:6:10 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ v[2] = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, VectorElement_BecomesNonUniform_AfterCondition) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var v : vec4<i32>;
+ if (v[2] == 0) {
+ v[2] = rw;
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, VectorElement_DifferentElementBecomesNonUniform) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var v : vec4<i32>;
+ v[1] = rw;
+ if (v[2] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (v[2] == 0) {
+ ^^
+
+test:6:10 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ v[1] = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, VectorElement_ElementBecomesUniform) {
+ // For aggregate types, we conservatively consider them to be forever non-uniform once they
+ // become non-uniform. Test that after assigning a uniform value to an element, that element is
+ // still considered to be non-uniform.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var v : vec4<i32>;
+ v[1] = rw;
+ v[1] = 42;
+ if (v[1] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (v[1] == 0) {
+ ^^
+
+test:6:10 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ v[1] = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, VectorElement_DifferentElementBecomesUniform) {
+ // For aggregate types, we conservatively consider them to be forever non-uniform once they
+ // become non-uniform. Test that after assigning a uniform value to an element, the whole vector
+ // is still considered to be non-uniform.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var v : vec4<i32>;
+ v[1] = rw;
+ v[2] = 42;
+ if (v[1] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (v[1] == 0) {
+ ^^
+
+test:6:10 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ v[1] = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, VectorElement_NonUniform_AnyBuiltin) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+fn foo() {
+ var v : vec4<i32>;
+ v[1] = non_uniform_global;
+ if (any(v == vec4(42))) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (any(v == vec4(42))) {
+ ^^
+
+test:6:10 note: reading from read_write storage buffer 'non_uniform_global' may result in a non-uniform value
+ v[1] = non_uniform_global;
+ ^^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, StructMember_Uniform) {
+ std::string src = R"(
+struct S {
+ a : i32,
+ b : i32,
+}
+@group(0) @binding(0) var<storage, read> s : S;
+
+fn foo() {
+ if (s.b == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, StructMember_NonUniform) {
+ std::string src = R"(
+struct S {
+ a : i32,
+ b : i32,
+}
+@group(0) @binding(0) var<storage, read_write> s : S;
+
+fn foo() {
+ if (s.b == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:10:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:9:3 note: control flow depends on non-uniform value
+ if (s.b == 0) {
+ ^^
+
+test:9:7 note: reading from read_write storage buffer 's' may result in a non-uniform value
+ if (s.b == 0) {
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, StructMember_BecomesNonUniform_BeforeCondition) {
+ std::string src = R"(
+struct S {
+ a : i32,
+ b : i32,
+}
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var s : S;
+ s.b = rw;
+ if (s.b == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:12:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:11:3 note: control flow depends on non-uniform value
+ if (s.b == 0) {
+ ^^
+
+test:10:9 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ s.b = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, StructMember_BecomesNonUniform_AfterCondition) {
+ std::string src = R"(
+struct S {
+ a : i32,
+ b : i32,
+}
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var s : S;
+ if (s.b == 0) {
+ s.b = rw;
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, StructMember_DifferentMemberBecomesNonUniform) {
+ std::string src = R"(
+struct S {
+ a : i32,
+ b : i32,
+}
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var s : S;
+ s.a = rw;
+ if (s.b == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:12:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:11:3 note: control flow depends on non-uniform value
+ if (s.b == 0) {
+ ^^
+
+test:10:9 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ s.a = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, StructMember_MemberBecomesUniform) {
+ // For aggregate types, we conservatively consider them to be forever non-uniform once they
+ // become non-uniform. Test that after assigning a uniform value to a member, that member is
+ // still considered to be non-uniform.
+ std::string src = R"(
+struct S {
+ a : i32,
+ b : i32,
+}
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var s : S;
+ s.a = rw;
+ s.a = 0;
+ if (s.a == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:13:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:12:3 note: control flow depends on non-uniform value
+ if (s.a == 0) {
+ ^^
+
+test:10:9 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ s.a = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, StructMember_DifferentMemberBecomesUniform) {
+ // For aggregate types, we conservatively consider them to be forever non-uniform once they
+ // become non-uniform. Test that after assigning a uniform value to a member, the whole struct
+ // is still considered to be non-uniform.
+ std::string src = R"(
+struct S {
+ a : i32,
+ b : i32,
+}
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var s : S;
+ s.a = rw;
+ s.b = 0;
+ if (s.a == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:13:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:12:3 note: control flow depends on non-uniform value
+ if (s.a == 0) {
+ ^^
+
+test:10:9 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ s.a = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ArrayElement_Uniform) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read> arr : array<i32>;
+
+fn foo() {
+ if (arr[7] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ArrayElement_NonUniform) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> arr : array<i32>;
+
+fn foo() {
+ if (arr[7] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (arr[7] == 0) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'arr' may result in a non-uniform value
+ if (arr[7] == 0) {
+ ^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ArrayElement_BecomesNonUniform_BeforeCondition) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var arr : array<i32, 4>;
+ arr[2] = rw;
+ if (arr[2] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (arr[2] == 0) {
+ ^^
+
+test:6:12 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ arr[2] = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ArrayElement_BecomesNonUniform_AfterCondition) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var arr : array<i32, 4>;
+ if (arr[2] == 0) {
+ arr[2] = rw;
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ArrayElement_DifferentElementBecomesNonUniform) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var arr : array<i32, 4>;
+ arr[1] = rw;
+ if (arr[2] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (arr[2] == 0) {
+ ^^
+
+test:6:12 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ arr[1] = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ArrayElement_DifferentElementBecomesNonUniformThroughPointer) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var arr : array<i32, 4>;
+ let pa = &arr[1];
+ *pa = rw;
+ if (arr[2] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (arr[2] == 0) {
+ ^^
+
+test:7:9 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ *pa = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ArrayElement_ElementBecomesUniform) {
+ // For aggregate types, we conservatively consider them to be forever non-uniform once they
+ // become non-uniform. Test that after assigning a uniform value to an element, that element is
+ // still considered to be non-uniform.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var arr : array<i32, 4>;
+ arr[1] = rw;
+ arr[1] = 42;
+ if (arr[1] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (arr[1] == 0) {
+ ^^
+
+test:6:12 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ arr[1] = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ArrayElement_DifferentElementBecomesUniform) {
+ // For aggregate types, we conservatively consider them to be forever non-uniform once they
+ // become non-uniform. Test that after assigning a uniform value to an element, the whole array
+ // is still considered to be non-uniform.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var arr : array<i32, 4>;
+ arr[1] = rw;
+ arr[2] = 42;
+ if (arr[1] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:9:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:8:3 note: control flow depends on non-uniform value
+ if (arr[1] == 0) {
+ ^^
+
+test:6:12 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ arr[1] = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ArrayElement_ElementBecomesUniformThroughPointer) {
+ // For aggregate types, we conservatively consider them to be forever non-uniform once they
+ // become non-uniform. Test that after assigning a uniform value to an element through a
+ // pointer, the whole array is still considered to be non-uniform.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var arr : array<i32, 4>;
+ let pa = &arr[2];
+ arr[1] = rw;
+ *pa = 42;
+ if (arr[1] == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:10:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:9:3 note: control flow depends on non-uniform value
+ if (arr[1] == 0) {
+ ^^
+
+test:7:12 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ arr[1] = rw;
+ ^^
+)");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Miscellaneous statement and expression tests.
+////////////////////////////////////////////////////////////////////////////////
+
+TEST_F(UniformityAnalysisTest, FunctionRequiresUniformFlowAndCausesNonUniformFlow) {
+ // Test that a function that requires uniform flow and then causes non-uniform flow can be
+ // called without error.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+fn foo() {
+ _ = dpdx(0.5);
+
+ if (non_uniform_global == 0) {
+ discard;
+ }
+}
+
+@stage(fragment)
+fn main() {
+ foo();
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, TypeConstructor) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+fn foo() {
+ if (i32(non_uniform_global) == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (i32(non_uniform_global) == 0) {
+ ^^
+
+test:5:11 note: reading from read_write storage buffer 'non_uniform_global' may result in a non-uniform value
+ if (i32(non_uniform_global) == 0) {
+ ^^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Conversion) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+fn foo() {
+ if (f32(non_uniform_global) == 0.0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (f32(non_uniform_global) == 0.0) {
+ ^^
+
+test:5:11 note: reading from read_write storage buffer 'non_uniform_global' may result in a non-uniform value
+ if (f32(non_uniform_global) == 0.0) {
+ ^^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Bitcast) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+fn foo() {
+ if (bitcast<f32>(non_uniform_global) == 0.0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (bitcast<f32>(non_uniform_global) == 0.0) {
+ ^^
+
+test:5:20 note: reading from read_write storage buffer 'non_uniform_global' may result in a non-uniform value
+ if (bitcast<f32>(non_uniform_global) == 0.0) {
+ ^^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, CompoundAssignment_NonUniformRHS) {
+ // Use compound assignment with a non-uniform RHS on a variable.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var v = 0;
+ v += rw;
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:6:8 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ v += rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, CompoundAssignment_UniformRHS_StillNonUniform) {
+ // Use compound assignment with a uniform RHS on a variable that is already non-uniform.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ var v = rw;
+ v += 1;
+ if (v == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:3 note: control flow depends on non-uniform value
+ if (v == 0) {
+ ^^
+
+test:5:11 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
+ var v = rw;
+ ^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, PhonyAssignment_LhsCausesNonUniformControlFlow) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> nonuniform_var : i32;
+
+fn bar() -> i32 {
+ if (nonuniform_var == 42) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+fn foo() {
+ _ = bar();
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:14:3 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:7 note: calling 'bar' may cause subsequent control flow to be non-uniform
+ _ = bar();
+ ^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (nonuniform_var == 42) {
+ ^^
+
+test:5:7 note: reading from read_write storage buffer 'nonuniform_var' may result in a non-uniform value
+ if (nonuniform_var == 42) {
+ ^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, ShortCircuiting_CausesNonUniformControlFlow) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform_global : i32;
+
+var<private> p : i32;
+
+fn main() {
+ let b = (non_uniform_global == 42) && false;
+ workgroupBarrier();
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:3 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:7:38 note: control flow depends on non-uniform value
+ let b = (non_uniform_global == 42) && false;
+ ^^
+
+test:7:12 note: reading from read_write storage buffer 'non_uniform_global' may result in a non-uniform value
+ let b = (non_uniform_global == 42) && false;
+ ^^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, DeadCode_AfterReturn) {
+ // Dead code after a return statement shouldn't cause uniformity errors.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ return;
+ if (non_uniform == 42) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, DeadCode_AfterDiscard) {
+ // Dead code after a discard statement shouldn't cause uniformity errors.
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ discard;
+ if (non_uniform == 42) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, ArrayLength) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> arr : array<f32>;
+
+fn foo() {
+ for (var i = 0u; i < arrayLength(&arr); i++) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, WorkgroupAtomics) {
+ std::string src = R"(
+var<workgroup> a : atomic<i32>;
+
+fn foo() {
+ if (atomicAdd(&a, 1) == 1) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (atomicAdd(&a, 1) == 1) {
+ ^^
+
+test:5:18 note: reading from workgroup storage variable 'a' may result in a non-uniform value
+ if (atomicAdd(&a, 1) == 1) {
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, StorageAtomics) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> a : atomic<i32>;
+
+fn foo() {
+ if (atomicAdd(&a, 1) == 1) {
+ storageBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:6:5 warning: 'storageBarrier' must only be called from uniform control flow
+ storageBarrier();
+ ^^^^^^^^^^^^^^
+
+test:5:3 note: control flow depends on non-uniform value
+ if (atomicAdd(&a, 1) == 1) {
+ ^^
+
+test:5:18 note: reading from read_write storage buffer 'a' may result in a non-uniform value
+ if (atomicAdd(&a, 1) == 1) {
+ ^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, DisableAnalysisWithExtension) {
+ std::string src = R"(
+enable chromium_disable_uniformity_analysis;
+
+@group(0) @binding(0) var<storage, read_write> rw : i32;
+
+fn foo() {
+ if (rw == 0) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, true);
+}
+
+TEST_F(UniformityAnalysisTest, StressGraphTraversalDepth) {
+ // Create a function with a very long sequence of variable declarations and assignments to
+ // test traversals of very deep graphs. This requires a non-recursive traversal algorithm.
+ ProgramBuilder b;
+ auto& ty = b.ty;
+
+ // var<private> v0 : i32 = 0i;
+ // fn foo() {
+ // let v1 = v0;
+ // let v2 = v1;
+ // ...
+ // let v{N} = v{N-1};
+ // if (v{N} == 0) {
+ // workgroupBarrier();
+ // }
+ // }
+ b.Global("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++) {
+ auto v = "v" + std::to_string(i);
+ foo_body.push_back(b.Decl(b.Var(v, nullptr, b.Expr(v_last))));
+ v_last = v;
+ }
+ foo_body.push_back(b.If(b.Equal(v_last, 0_i), b.Block(b.CallStmt(b.Call("workgroupBarrier")))));
+ b.Func("foo", {}, ty.void_(), foo_body);
+
+ // TODO(jrprice): Expect false when uniformity issues become errors.
+ EXPECT_TRUE(RunTest(std::move(b))) << error_;
+ EXPECT_EQ(error_,
+ R"(warning: 'workgroupBarrier' must only be called from uniform control flow
+note: control flow depends on non-uniform value
+note: reading from module-scope private variable 'v0' may result in a non-uniform value)");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Tests for the quality of the error messages produced by the analysis.
+////////////////////////////////////////////////////////////////////////////////
+
+TEST_F(UniformityAnalysisTest, Error_CallUserThatCallsBuiltinDirectly) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn foo() {
+ workgroupBarrier();
+}
+
+fn main() {
+ if (non_uniform == 42) {
+ foo();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:10:5 warning: 'foo' must only be called from uniform control flow
+ foo();
+ ^^^
+
+test:5:3 note: 'foo' requires uniformity because it calls workgroupBarrier
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:9:3 note: control flow depends on non-uniform value
+ if (non_uniform == 42) {
+ ^^
+
+test:9:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ if (non_uniform == 42) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Error_CallUserThatCallsBuiltinIndirectly) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn zoo() {
+ workgroupBarrier();
+}
+
+fn bar() {
+ zoo();
+}
+
+fn foo() {
+ bar();
+}
+
+fn main() {
+ if (non_uniform == 42) {
+ foo();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:18:5 warning: 'foo' must only be called from uniform control flow
+ foo();
+ ^^^
+
+test:5:3 note: 'foo' requires uniformity because it indirectly calls workgroupBarrier
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:17:3 note: control flow depends on non-uniform value
+ if (non_uniform == 42) {
+ ^^
+
+test:17:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ if (non_uniform == 42) {
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Error_ParametersRequireUniformityInChain) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn zoo(a : i32) {
+ if (a == 42) {
+ workgroupBarrier();
+ }
+}
+
+fn bar(b : i32) {
+ zoo(b);
+}
+
+fn foo(c : i32) {
+ bar(c);
+}
+
+fn main() {
+ foo(non_uniform);
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:19:7 warning: parameter 'c' of 'foo' must be uniform
+ foo(non_uniform);
+ ^^^^^^^^^^^
+
+test:15:7 note: parameter 'b' of 'bar' must be uniform
+ bar(c);
+ ^
+
+test:11:7 note: parameter 'a' of 'zoo' must be uniform
+ zoo(b);
+ ^
+
+test:6:5 note: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:19:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
+ foo(non_uniform);
+ ^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Error_ReturnValueMayBeNonUniformChain) {
+ std::string src = R"(
+@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
+
+fn zoo() -> i32 {
+ return non_uniform;
+}
+
+fn bar() -> i32 {
+ return zoo();
+}
+
+fn foo() -> i32 {
+ return bar();
+}
+
+fn main() {
+ if (foo() == 42) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:18:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:17:3 note: control flow depends on non-uniform value
+ if (foo() == 42) {
+ ^^
+
+test:17:7 note: return value of 'foo' may be non-uniform
+ if (foo() == 42) {
+ ^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Error_SubsequentControlFlowMayBeNonUniform) {
+ // Make sure we correctly identify the function call as the source of non-uniform control flow
+ // and not the if statement with the uniform condition.
+ std::string src = R"(
+@group(0) @binding(0) var<uniform> uniform_value : i32;
+@group(0) @binding(1) var<storage, read_write> non_uniform_value : i32;
+
+fn foo() -> i32 {
+ if (non_uniform_value == 0) {
+ return 5;
+ }
+ return 6;
+}
+
+fn main() {
+ foo();
+ if (uniform_value == 42) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:15:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:3 note: calling 'foo' may cause subsequent control flow to be non-uniform
+ foo();
+ ^^^
+
+test:6:3 note: control flow depends on non-uniform value
+ if (non_uniform_value == 0) {
+ ^^
+
+test:6:7 note: reading from read_write storage buffer 'non_uniform_value' may result in a non-uniform value
+ if (non_uniform_value == 0) {
+ ^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Error_ParameterRequiredToBeUniformForSubsequentControlFlow) {
+ // Make sure we correctly identify the function call as the source of non-uniform control flow
+ // and not the if statement with the uniform condition.
+ std::string src = R"(
+@group(0) @binding(0) var<uniform> uniform_value : i32;
+@group(0) @binding(1) var<storage, read_write> non_uniform_value : i32;
+
+fn foo(x : i32) -> i32 {
+ if (x == 0) {
+ return 5;
+ }
+ return 6;
+}
+
+fn main() {
+ foo(non_uniform_value);
+ if (uniform_value == 42) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:15:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:13:7 note: non-uniform function call argument causes subsequent control flow to be non-uniform
+ foo(non_uniform_value);
+ ^^^^^^^^^^^^^^^^^
+
+test:6:3 note: control flow depends on non-uniform value
+ if (x == 0) {
+ ^^
+
+test:6:7 note: reading from 'x' may result in a non-uniform value
+ if (x == 0) {
+ ^
+
+test:13:7 note: reading from read_write storage buffer 'non_uniform_value' may result in a non-uniform value
+ foo(non_uniform_value);
+ ^^^^^^^^^^^^^^^^^
+)");
+}
+
+TEST_F(UniformityAnalysisTest, Error_ShortCircuitingExprCausesNonUniformControlFlow) {
+ // Make sure we correctly identify the short-circuit as the source of non-uniform control flow
+ // and not the if statement with the uniform condition.
+ std::string src = R"(
+@group(0) @binding(0) var<uniform> uniform_value : i32;
+@group(0) @binding(1) var<storage, read_write> non_uniform_value : i32;
+
+fn main() {
+ let b = (non_uniform_value == 0) && true;
+ if (uniform_value == 42) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ RunTest(src, false);
+ EXPECT_EQ(error_,
+ R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+ workgroupBarrier();
+ ^^^^^^^^^^^^^^^^
+
+test:6:36 note: control flow depends on non-uniform value
+ let b = (non_uniform_value == 0) && true;
+ ^^
+
+test:6:12 note: reading from read_write storage buffer 'non_uniform_value' may result in a non-uniform value
+ let b = (non_uniform_value == 0) && true;
+ ^^^^^^^^^^^^^^^^^
+)");
+}
+
+} // namespace
+} // namespace tint::resolver
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index f9b0ba7..9f698e6 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -194,7 +194,7 @@
// https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable-types
bool Validator::IsHostShareable(const sem::Type* type) const {
- if (type->IsAnyOf<sem::I32, sem::U32, sem::F32>()) {
+ if (type->IsAnyOf<sem::I32, sem::U32, sem::F32, sem::F16>()) {
return true;
}
return Switch(
@@ -652,6 +652,13 @@
return false;
}
+ if (auto* r = storage_ty->As<sem::SampledTexture>()) {
+ if (!r->type()->UnwrapRef()->is_numeric_scalar()) {
+ AddError("texture_2d<type>: type must be f32, i32 or u32", decl->source);
+ return false;
+ }
+ }
+
if (auto* r = storage_ty->As<sem::MultisampledTexture>()) {
if (r->dim() != ast::TextureDimension::k2d) {
AddError("only 2d multisampled textures are supported", decl->source);
@@ -1356,6 +1363,35 @@
return true;
}
+bool Validator::Call(const sem::Call* call, sem::Statement* current_statement) const {
+ auto* expr = call->Declaration();
+ bool is_call_stmt =
+ current_statement && Is<ast::CallStatement>(current_statement->Declaration(),
+ [&](auto* stmt) { return stmt->expr == expr; });
+
+ return Switch(
+ call->Target(), //
+ [&](const sem::TypeConversion*) {
+ if (is_call_stmt) {
+ AddError("type conversion evaluated but not used", call->Declaration()->source);
+ return false;
+ }
+ return true;
+ },
+ [&](const sem::TypeConstructor* ctor) {
+ if (is_call_stmt) {
+ AddError("type constructor evaluated but not used", call->Declaration()->source);
+ return false;
+ }
+ return Switch(
+ ctor->ReturnType(), //
+ [&](const sem::Array* arr) { return ArrayConstructor(expr, arr); },
+ [&](const sem::Struct* str) { return StructureConstructor(expr, str); },
+ [&](Default) { return true; });
+ },
+ [&](Default) { return true; });
+}
+
bool Validator::DiscardStatement(const sem::Statement* stmt,
sem::Statement* current_statement) const {
if (auto* continuing = ClosestContinuing(/*stop_at_loop*/ false, current_statement)) {
@@ -1486,7 +1522,7 @@
if (is_const_expr) {
auto vector = builtin->Parameters()[index]->Type()->Is<sem::Vector>();
for (size_t i = 0; i < values.Elements().size(); i++) {
- auto value = values.Elements()[i].i32;
+ auto value = values.Element<AInt>(i).value;
if (value < min || value > max) {
if (vector) {
AddError("each component of the " + name +
@@ -1517,21 +1553,22 @@
check_arg_is_constexpr(sem::ParameterUsage::kComponent, 0, 3);
}
-bool Validator::RequiredExtensionForBuiltinFunction(const sem::Call* call,
- const ast::ExtensionSet& extensionSet) const {
+bool Validator::RequiredExtensionForBuiltinFunction(
+ const sem::Call* call,
+ const ast::Extensions& enabled_extensions) const {
const auto* builtin = call->Target()->As<sem::Builtin>();
if (!builtin) {
return true;
}
const auto extension = builtin->RequiredExtension();
- if (extension == ast::Enable::ExtensionKind::kNotAnExtension) {
+ if (extension == ast::Extension::kNone) {
return true;
}
- if (extensionSet.find(extension) == extensionSet.cend()) {
+ if (!enabled_extensions.contains(extension)) {
AddError("cannot call built-in function '" + std::string(builtin->str()) +
- "' without extension " + ast::Enable::KindToName(extension),
+ "' without extension " + ast::str(extension),
call->Declaration()->source);
return false;
}
@@ -1649,8 +1686,8 @@
return true;
}
-bool Validator::StructureConstructorOrCast(const ast::CallExpression* ctor,
- const sem::Struct* struct_type) const {
+bool Validator::StructureConstructor(const ast::CallExpression* ctor,
+ const sem::Struct* struct_type) const {
if (!struct_type->IsConstructible()) {
AddError("struct constructor has non-constructible type", ctor->source);
return false;
@@ -1682,8 +1719,8 @@
return true;
}
-bool Validator::ArrayConstructorOrCast(const ast::CallExpression* ctor,
- const sem::Array* array_type) const {
+bool Validator::ArrayConstructor(const ast::CallExpression* ctor,
+ const sem::Array* array_type) const {
auto& values = ctor->args;
auto* elem_ty = array_type->ElemType();
for (auto* value : values) {
@@ -1721,66 +1758,6 @@
return true;
}
-bool Validator::VectorConstructorOrCast(const ast::CallExpression* ctor,
- const sem::Vector* vec_type) const {
- auto& values = ctor->args;
- auto* elem_ty = vec_type->type();
- size_t value_cardinality_sum = 0;
- for (auto* value : values) {
- auto* value_ty = sem_.TypeOf(value)->UnwrapRef();
- if (value_ty->is_scalar()) {
- if (elem_ty != value_ty) {
- AddError(
- "type in vector constructor does not match vector type: "
- "expected '" +
- sem_.TypeNameOf(elem_ty) + "', found '" + sem_.TypeNameOf(value_ty) + "'",
- value->source);
- return false;
- }
-
- value_cardinality_sum++;
- } else if (auto* value_vec = value_ty->As<sem::Vector>()) {
- auto* value_elem_ty = value_vec->type();
- // A mismatch of vector type parameter T is only an error if multiple
- // arguments are present. A single argument constructor constitutes a
- // type conversion expression.
- if (elem_ty != value_elem_ty && values.size() > 1u) {
- AddError(
- "type in vector constructor does not match vector type: "
- "expected '" +
- sem_.TypeNameOf(elem_ty) + "', found '" + sem_.TypeNameOf(value_elem_ty) +
- "'",
- value->source);
- return false;
- }
-
- value_cardinality_sum += value_vec->Width();
- } else {
- // A vector constructor can only accept vectors and scalars.
- AddError("expected vector or scalar type in vector constructor; found: " +
- sem_.TypeNameOf(value_ty),
- value->source);
- return false;
- }
- }
-
- // A correct vector constructor must either be a zero-value expression,
- // a single-value initializer (splat) expression, or the number of components
- // of all constructor arguments must add up to the vector cardinality.
- if (value_cardinality_sum > 1 && value_cardinality_sum != vec_type->Width()) {
- if (values.empty()) {
- TINT_ICE(Resolver, diagnostics_) << "constructor arguments expected to be non-empty!";
- }
- const Source& values_start = values[0]->source;
- const Source& values_end = values[values.size() - 1]->source;
- AddError("attempted to construct '" + sem_.TypeNameOf(vec_type) + "' with " +
- std::to_string(value_cardinality_sum) + " component(s)",
- Source::Combine(values_start, values_end));
- return false;
- }
- return true;
-}
-
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);
@@ -1797,115 +1774,6 @@
return true;
}
-bool Validator::MatrixConstructorOrCast(const ast::CallExpression* ctor,
- const sem::Matrix* matrix_ty) const {
- auto& values = ctor->args;
- // Zero Value expression
- if (values.empty()) {
- return true;
- }
-
- if (!Matrix(matrix_ty, ctor->source)) {
- return false;
- }
-
- std::vector<const sem::Type*> arg_tys;
- arg_tys.reserve(values.size());
- for (auto* value : values) {
- arg_tys.emplace_back(sem_.TypeOf(value)->UnwrapRef());
- }
-
- auto* elem_type = matrix_ty->type();
- auto num_elements = matrix_ty->columns() * matrix_ty->rows();
-
- // Print a generic error for an invalid matrix constructor, showing the
- // available overloads.
- auto print_error = [&]() {
- const Source& values_start = values[0]->source;
- const Source& values_end = values[values.size() - 1]->source;
- auto type_name = sem_.TypeNameOf(matrix_ty);
- auto elem_type_name = sem_.TypeNameOf(elem_type);
- std::stringstream ss;
- ss << "no matching constructor " + type_name << "(";
- for (size_t i = 0; i < values.size(); i++) {
- if (i > 0) {
- ss << ", ";
- }
- ss << arg_tys[i]->FriendlyName(symbols_);
- }
- ss << ")" << std::endl << std::endl;
- ss << "3 candidates available:" << std::endl;
- ss << " " << type_name << "()" << std::endl;
- ss << " " << type_name << "(" << elem_type_name << ",...," << elem_type_name << ")"
- << " // " << std::to_string(num_elements) << " arguments" << std::endl;
- ss << " " << type_name << "(";
- for (uint32_t c = 0; c < matrix_ty->columns(); c++) {
- if (c > 0) {
- ss << ", ";
- }
- ss << VectorPretty(matrix_ty->rows(), elem_type);
- }
- ss << ")" << std::endl;
- AddError(ss.str(), Source::Combine(values_start, values_end));
- };
-
- const sem::Type* expected_arg_type = nullptr;
- if (num_elements == values.size()) {
- // Column-major construction from scalar elements.
- expected_arg_type = matrix_ty->type();
- } else if (matrix_ty->columns() == values.size()) {
- // Column-by-column construction from vectors.
- expected_arg_type = matrix_ty->ColumnType();
- } else {
- print_error();
- return false;
- }
-
- for (auto* arg_ty : arg_tys) {
- if (arg_ty != expected_arg_type) {
- print_error();
- return false;
- }
- }
-
- return true;
-}
-
-bool Validator::ScalarConstructorOrCast(const ast::CallExpression* ctor,
- const sem::Type* ty) const {
- if (ctor->args.size() == 0) {
- return true;
- }
- if (ctor->args.size() > 1) {
- AddError(
- "expected zero or one value in constructor, got " + std::to_string(ctor->args.size()),
- ctor->source);
- return false;
- }
-
- // Validate constructor
- auto* value = ctor->args[0];
- auto* value_ty = sem_.TypeOf(value)->UnwrapRef();
-
- using Bool = sem::Bool;
- using I32 = sem::I32;
- using U32 = sem::U32;
- using F32 = sem::F32;
-
- const bool is_valid =
- (ty->Is<Bool>() && value_ty->is_scalar()) || (ty->Is<I32>() && value_ty->is_scalar()) ||
- (ty->Is<U32>() && value_ty->is_scalar()) || (ty->Is<F32>() && value_ty->is_scalar());
- if (!is_valid) {
- AddError("cannot construct '" + sem_.TypeNameOf(ty) + "' with a value of type '" +
- sem_.TypeNameOf(value_ty) + "'",
- ctor->source);
-
- return false;
- }
-
- return true;
-}
-
bool Validator::PipelineStages(const std::vector<sem::Function*>& entry_points) const {
auto check_workgroup_storage = [&](const sem::Function* func,
const sem::Function* entry_point) {
diff --git a/src/tint/resolver/validator.h b/src/tint/resolver/validator.h
index 21c8e70..a8c18d5 100644
--- a/src/tint/resolver/validator.h
+++ b/src/tint/resolver/validator.h
@@ -183,6 +183,12 @@
/// @returns true on success, false otherwise
bool ContinueStatement(const sem::Statement* stmt, sem::Statement* current_statement) const;
+ /// Validates a call
+ /// @param call the call
+ /// @param current_statement the current statement being resolved
+ /// @returns true on success, false otherwise
+ bool Call(const sem::Call* call, sem::Statement* current_statement) const;
+
/// Validates a discard statement
/// @param stmt the statement to validate
/// @param current_statement the current statement being resolved
@@ -308,12 +314,12 @@
/// @returns true on success, false otherwise.
bool Structure(const sem::Struct* str, ast::PipelineStage stage) const;
- /// Validates a structure constructor or cast
+ /// Validates a structure constructor
/// @param ctor the call expression to validate
/// @param struct_type the type of the structure
/// @returns true on success, false otherwise
- bool StructureConstructorOrCast(const ast::CallExpression* ctor,
- const sem::Struct* struct_type) const;
+ bool StructureConstructor(const ast::CallExpression* ctor,
+ const sem::Struct* struct_type) const;
/// Validates a switch statement
/// @param s the switch to validate
@@ -342,31 +348,11 @@
/// @returns true on success, false otherwise
bool Vector(const sem::Vector* ty, const Source& source) const;
- /// Validates a vector constructor or cast
- /// @param ctor the call expression to validate
- /// @param vec_type the vector type
- /// @returns true on success, false otherwise
- bool VectorConstructorOrCast(const ast::CallExpression* ctor,
- const sem::Vector* vec_type) const;
-
- /// Validates a matrix constructor or cast
- /// @param ctor the call expression to validate
- /// @param matrix_type the type of the matrix
- /// @returns true on success, false otherwise
- bool MatrixConstructorOrCast(const ast::CallExpression* ctor,
- const sem::Matrix* matrix_type) const;
-
- /// Validates a scalar constructor or cast
- /// @param ctor the call expression to validate
- /// @param type the type of the scalar
- /// @returns true on success, false otherwise.
- bool ScalarConstructorOrCast(const ast::CallExpression* ctor, const sem::Type* type) const;
-
- /// Validates an array constructor or cast
+ /// Validates an array constructor
/// @param ctor the call expresion to validate
/// @param arr_type the type of the array
/// @returns true on success, false otherwise
- bool ArrayConstructorOrCast(const ast::CallExpression* ctor, const sem::Array* arr_type) const;
+ bool ArrayConstructor(const ast::CallExpression* ctor, const sem::Array* arr_type) const;
/// Validates a texture builtin function
/// @param call the builtin call to validate
@@ -375,10 +361,10 @@
/// Validates an optional builtin function and its required extension.
/// @param call the builtin call to validate
- /// @param extensionSet all the extensions declared in current module
+ /// @param enabled_extensions all the extensions declared in current module
/// @returns true on success, false otherwise
bool RequiredExtensionForBuiltinFunction(const sem::Call* call,
- const ast::ExtensionSet& extensionSet) const;
+ const ast::Extensions& enabled_extensions) const;
/// Validates there are no duplicate attributes
/// @param attributes the list of attributes to validate
diff --git a/src/tint/resolver/var_let_test.cc b/src/tint/resolver/var_let_test.cc
index 4c62bdd..4306736 100644
--- a/src/tint/resolver/var_let_test.cc
+++ b/src/tint/resolver/var_let_test.cc
@@ -86,7 +86,7 @@
// struct S { i : i32; }
// alias A = S;
// fn F(){
- // var i : i32 = 1;
+ // var i : i32 = 1i;
// var u : u32 = 1u;
// var f : f32 = 1.f;
// var b : bool = true;
diff --git a/src/tint/scope_stack.h b/src/tint/scope_stack.h
index 8bc97a3..6838f5b 100644
--- a/src/tint/scope_stack.h
+++ b/src/tint/scope_stack.h
@@ -24,7 +24,7 @@
/// Used to store a stack of scope information.
/// The stack starts with a global scope which can not be popped.
-template <class T>
+template <class K, class V>
class ScopeStack {
public:
/// Constructor
@@ -47,32 +47,42 @@
}
/// Assigns the value into the top most scope of the stack.
- /// @param symbol the symbol of the value
+ /// @param key the key of the value
/// @param val the value
- /// @returns the old value if there was an existing symbol at the top of the
+ /// @returns the old value if there was an existing key at the top of the
/// stack, otherwise the zero initializer for type T.
- T Set(const Symbol& symbol, T val) {
- std::swap(val, stack_.back()[symbol]);
+ V Set(const K& key, V val) {
+ std::swap(val, stack_.back()[key]);
return val;
}
/// Retrieves a value from the stack
- /// @param symbol the symbol to look for
+ /// @param key the key to look for
/// @returns the value, or the zero initializer if the value was not found
- T Get(const Symbol& symbol) const {
+ V Get(const K& key) const {
for (auto iter = stack_.rbegin(); iter != stack_.rend(); ++iter) {
auto& map = *iter;
- auto val = map.find(symbol);
+ auto val = map.find(key);
if (val != map.end()) {
return val->second;
}
}
- return T{};
+ return V{};
+ }
+
+ /// Return the top scope of the stack.
+ /// @returns the top scope of the stack
+ const std::unordered_map<K, V>& Top() const { return stack_.back(); }
+
+ /// Clear the scope stack.
+ void Clear() {
+ stack_.clear();
+ stack_.push_back({});
}
private:
- std::vector<std::unordered_map<Symbol, T>> stack_;
+ std::vector<std::unordered_map<K, V>> stack_;
};
} // namespace tint
diff --git a/src/tint/scope_stack_test.cc b/src/tint/scope_stack_test.cc
index 8062807..aeb7e73 100644
--- a/src/tint/scope_stack_test.cc
+++ b/src/tint/scope_stack_test.cc
@@ -22,7 +22,7 @@
class ScopeStackTest : public ProgramBuilder, public testing::Test {};
TEST_F(ScopeStackTest, Get) {
- ScopeStack<uint32_t> s;
+ ScopeStack<Symbol, uint32_t> s;
Symbol a(1, ID());
Symbol b(3, ID());
s.Push();
@@ -44,13 +44,13 @@
}
TEST_F(ScopeStackTest, Get_MissingSymbol) {
- ScopeStack<uint32_t> s;
+ ScopeStack<Symbol, uint32_t> s;
Symbol sym(1, ID());
EXPECT_EQ(s.Get(sym), 0u);
}
TEST_F(ScopeStackTest, Set) {
- ScopeStack<uint32_t> s;
+ ScopeStack<Symbol, uint32_t> s;
Symbol a(1, ID());
Symbol b(2, ID());
@@ -67,5 +67,25 @@
EXPECT_EQ(s.Get(b), 25u);
}
+TEST_F(ScopeStackTest, Clear) {
+ ScopeStack<Symbol, uint32_t> s;
+ Symbol a(1, ID());
+ Symbol b(2, ID());
+
+ EXPECT_EQ(s.Set(a, 5u), 0u);
+ EXPECT_EQ(s.Get(a), 5u);
+
+ s.Push();
+
+ EXPECT_EQ(s.Set(b, 10u), 0u);
+ EXPECT_EQ(s.Get(b), 10u);
+
+ s.Push();
+
+ s.Clear();
+ EXPECT_EQ(s.Get(a), 0u);
+ EXPECT_EQ(s.Get(b), 0u);
+}
+
} // namespace
} // namespace tint
diff --git a/src/tint/sem/abstract_float.cc b/src/tint/sem/abstract_float.cc
index 1f0c8b4..6f32e99 100644
--- a/src/tint/sem/abstract_float.cc
+++ b/src/tint/sem/abstract_float.cc
@@ -34,7 +34,7 @@
}
std::string AbstractFloat::FriendlyName(const SymbolTable&) const {
- return "AbstractFloat";
+ return "abstract-float";
}
} // namespace tint::sem
diff --git a/src/tint/sem/abstract_int.cc b/src/tint/sem/abstract_int.cc
index 6851514..682c50a 100644
--- a/src/tint/sem/abstract_int.cc
+++ b/src/tint/sem/abstract_int.cc
@@ -34,7 +34,7 @@
}
std::string AbstractInt::FriendlyName(const SymbolTable&) const {
- return "AbstractInt";
+ return "abstract-int";
}
} // namespace tint::sem
diff --git a/src/tint/sem/builtin.cc b/src/tint/sem/builtin.cc
index 0328a64..bb2878b 100644
--- a/src/tint/sem/builtin.cc
+++ b/src/tint/sem/builtin.cc
@@ -83,6 +83,10 @@
i == sem::BuiltinType::kAtomicCompareExchangeWeak;
}
+bool IsDP4aBuiltin(BuiltinType i) {
+ return i == sem::BuiltinType::kDot4I8Packed || i == sem::BuiltinType::kDot4U8Packed;
+}
+
Builtin::Builtin(BuiltinType type,
const sem::Type* return_type,
std::vector<Parameter*> parameters,
@@ -135,6 +139,10 @@
return IsAtomicBuiltin(type_);
}
+bool Builtin::IsDP4a() const {
+ return IsDP4aBuiltin(type_);
+}
+
bool Builtin::HasSideEffects() const {
if (IsAtomic() && type_ != sem::BuiltinType::kAtomicLoad) {
return true;
@@ -145,14 +153,11 @@
return false;
}
-ast::Enable::ExtensionKind Builtin::RequiredExtension() const {
- switch (type_) {
- case sem::BuiltinType::kDot4I8Packed:
- case sem::BuiltinType::kDot4U8Packed:
- return ast::Enable::ExtensionKind::kChromiumExperimentalDP4a;
- default:
- return ast::Enable::ExtensionKind::kNotAnExtension;
+ast::Extension Builtin::RequiredExtension() const {
+ if (IsDP4a()) {
+ return ast::Extension::kChromiumExperimentalDP4a;
}
+ return ast::Extension::kNone;
}
} // namespace tint::sem
diff --git a/src/tint/sem/builtin.h b/src/tint/sem/builtin.h
index 8d3e2bd..1dc61ad 100644
--- a/src/tint/sem/builtin.h
+++ b/src/tint/sem/builtin.h
@@ -18,6 +18,7 @@
#include <string>
#include <vector>
+#include "src/tint/ast/extension.h"
#include "src/tint/sem/builtin_type.h"
#include "src/tint/sem/call_target.h"
#include "src/tint/sem/pipeline_stage_set.h"
@@ -70,6 +71,11 @@
/// @returns true if the given `i` is a atomic builtin
bool IsAtomicBuiltin(BuiltinType i);
+/// Determins if the given `i` is a DP4a builtin
+/// @param i the builtin
+/// @returns true if the given `i` is a DP4a builtin
+bool IsDP4aBuiltin(BuiltinType i);
+
/// Builtin holds the semantic information for a builtin function.
class Builtin final : public Castable<Builtin, CallTarget> {
public:
@@ -130,13 +136,17 @@
/// @returns true if builtin is a atomic builtin
bool IsAtomic() const;
+ /// @returns true if builtin is a DP4a builtin (defined in the extension
+ /// chromium_experimental_DP4a)
+ bool IsDP4a() const;
+
/// @returns true if intrinsic may have side-effects (i.e. writes to at least
/// one of its inputs)
bool HasSideEffects() const;
/// @returns the required extension of this builtin function. Returns
- /// ast::Enable::ExtensionKind::kNotAnExtension if no extension is required.
- ast::Enable::ExtensionKind RequiredExtension() const;
+ /// ast::Extension::kNone if no extension is required.
+ ast::Extension RequiredExtension() const;
private:
const BuiltinType type_;
diff --git a/src/tint/sem/constant.cc b/src/tint/sem/constant.cc
index f5c82a2..98c724c 100644
--- a/src/tint/sem/constant.cc
+++ b/src/tint/sem/constant.cc
@@ -14,7 +14,6 @@
#include "src/tint/sem/constant.h"
-#include <functional>
#include <utility>
#include "src/tint/debug.h"
@@ -25,24 +24,19 @@
namespace {
-const Type* ElemType(const Type* ty, size_t num_elements) {
+const Type* CheckElemType(const Type* ty, size_t num_scalars) {
diag::List diag;
- if (ty->is_scalar()) {
- if (num_elements != 1) {
- TINT_ICE(Semantic, diag) << "sem::Constant() type <-> num_element mismatch. type: '"
- << ty->TypeInfo().name << "' num_elements: " << num_elements;
+ if (ty->is_abstract_or_scalar() || ty->IsAnyOf<Vector, Matrix>()) {
+ uint32_t count = 0;
+ auto* el_ty = Type::ElementOf(ty, &count);
+ if (num_scalars != count) {
+ TINT_ICE(Semantic, diag) << "sem::Constant() type <-> scalar mismatch. type: '"
+ << ty->TypeInfo().name << "' scalar: " << num_scalars;
}
- return ty;
+ TINT_ASSERT(Semantic, el_ty->is_abstract_or_scalar());
+ return el_ty;
}
- if (auto* vec = ty->As<Vector>()) {
- if (num_elements != vec->Width()) {
- TINT_ICE(Semantic, diag) << "sem::Constant() type <-> num_element mismatch. type: '"
- << ty->TypeInfo().name << "' num_elements: " << num_elements;
- }
- TINT_ASSERT(Semantic, vec->type()->is_scalar());
- return vec->type();
- }
- TINT_UNREACHABLE(Semantic, diag) << "Unsupported sem::Constant type";
+ TINT_UNREACHABLE(Semantic, diag) << "Unsupported sem::Constant type: " << ty->TypeInfo().name;
return nullptr;
}
@@ -51,7 +45,7 @@
Constant::Constant() {}
Constant::Constant(const sem::Type* ty, Scalars els)
- : type_(ty), elem_type_(ElemType(ty, els.size())), elems_(std::move(els)) {}
+ : type_(ty), elem_type_(CheckElemType(ty, els.size())), elems_(std::move(els)) {}
Constant::Constant(const Constant&) = default;
@@ -60,16 +54,12 @@
Constant& Constant::operator=(const Constant& rhs) = default;
bool Constant::AnyZero() const {
- for (size_t i = 0; i < Elements().size(); ++i) {
- if (WithScalarAt(i, [&](auto&& s) {
- // Use std::equal_to to work around -Wfloat-equal warnings
- using T = std::remove_reference_t<decltype(s)>;
- auto equal_to = std::equal_to<T>{};
- if (equal_to(s, T(0))) {
- return true;
- }
- return false;
- })) {
+ for (auto scalar : elems_) {
+ auto is_zero = [&](auto&& s) {
+ using T = std::remove_reference_t<decltype(s)>;
+ return s == T(0);
+ };
+ if (std::visit(is_zero, scalar)) {
return true;
}
}
diff --git a/src/tint/sem/constant.h b/src/tint/sem/constant.h
index 673446f..ea143b6 100644
--- a/src/tint/sem/constant.h
+++ b/src/tint/sem/constant.h
@@ -15,6 +15,7 @@
#ifndef SRC_TINT_SEM_CONSTANT_H_
#define SRC_TINT_SEM_CONSTANT_H_
+#include <variant>
#include <vector>
#include "src/tint/program_builder.h"
@@ -26,34 +27,8 @@
/// list of scalar values. Value may be of a scalar or vector type.
class Constant {
public:
- /// Scalar holds a single constant scalar value, as a union of an i32, u32,
- /// f32 or boolean.
- union Scalar {
- /// The scalar value as a i32
- tint::i32 i32;
- /// The scalar value as a u32
- tint::u32 u32;
- /// The scalar value as a f32
- tint::f32 f32;
- /// The scalar value as a bool
- bool bool_;
-
- /// Constructs the scalar with the i32 value `v`
- /// @param v the value of the Scalar
- Scalar(tint::i32 v) : i32(v) {} // NOLINT
-
- /// Constructs the scalar with the u32 value `v`
- /// @param v the value of the Scalar
- Scalar(tint::u32 v) : u32(v) {} // NOLINT
-
- /// Constructs the scalar with the f32 value `v`
- /// @param v the value of the Scalar
- Scalar(tint::f32 v) : f32(v) {} // NOLINT
-
- /// Constructs the scalar with the bool value `v`
- /// @param v the value of the Scalar
- Scalar(bool v) : bool_(v) {} // NOLINT
- };
+ /// Scalar holds a single constant scalar value - one of: AInt, AFloat or bool.
+ using Scalar = std::variant<AInt, AFloat, bool>;
/// Scalars is a list of scalar values
using Scalars = std::vector<Scalar>;
@@ -95,32 +70,25 @@
/// @returns true if any scalar element is zero
bool AnyZero() const;
- /// Calls `func(s)` with s being the current scalar value at `index`.
- /// `func` is typically a lambda of the form '[](auto&& s)'.
/// @param index the index of the scalar value
- /// @param func a function with signature `T(S)`
- /// @return the value returned by func.
- template <typename Func>
- auto WithScalarAt(size_t index, Func&& func) const {
- return Switch(
- ElementType(), //
- [&](const I32*) { return func(elems_[index].i32); },
- [&](const U32*) { return func(elems_[index].u32); },
- [&](const F32*) { return func(elems_[index].f32); },
- [&](const Bool*) { return func(elems_[index].bool_); },
- [&](Default) {
- diag::List diags;
- TINT_UNREACHABLE(Semantic, diags)
- << "invalid scalar type " << type_->TypeInfo().name;
- return func(u32(0u));
- });
+ /// @return the value of the scalar at `index`, which must be of type `T`.
+ template <typename T>
+ T Element(size_t index) const {
+ return std::get<T>(elems_[index]);
}
/// @param index the index of the scalar value
/// @return the value of the scalar `static_cast` to type T.
template <typename T>
T ElementAs(size_t index) const {
- return WithScalarAt(index, [](auto val) { return static_cast<T>(val); });
+ return Cast<T>(elems_[index]);
+ }
+
+ /// @param s the input scalar
+ /// @returns the scalar `s` cast to the type `T`.
+ template <typename T>
+ static T Cast(Scalar s) {
+ return std::visit([](auto v) { return static_cast<T>(v); }, s);
}
private:
diff --git a/src/tint/sem/expression.cc b/src/tint/sem/expression.cc
index 40fbb58..57ec68b 100644
--- a/src/tint/sem/expression.cc
+++ b/src/tint/sem/expression.cc
@@ -16,6 +16,8 @@
#include <utility>
+#include "src/tint/sem/materialize.h"
+
TINT_INSTANTIATE_TYPEINFO(tint::sem::Expression);
namespace tint::sem {
@@ -37,4 +39,11 @@
Expression::~Expression() = default;
+const Expression* Expression::UnwrapMaterialize() const {
+ if (auto* m = As<Materialize>()) {
+ return m->Expr();
+ }
+ return this;
+}
+
} // namespace tint::sem
diff --git a/src/tint/sem/expression.h b/src/tint/sem/expression.h
index 13f493b..a783851 100644
--- a/src/tint/sem/expression.h
+++ b/src/tint/sem/expression.h
@@ -76,6 +76,9 @@
/// @return true of this expression may have side effects
bool HasSideEffects() const { return has_side_effects_; }
+ /// @return the inner expression node if this is a Materialize, otherwise this.
+ const Expression* UnwrapMaterialize() const;
+
protected:
/// The AST expression node for this semantic expression
const ast::Expression* const declaration_;
diff --git a/src/tint/sem/expression_test.cc b/src/tint/sem/expression_test.cc
new file mode 100644
index 0000000..fc1adeb
--- /dev/null
+++ b/src/tint/sem/expression_test.cc
@@ -0,0 +1,39 @@
+// 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/expression.h"
+
+#include "src/tint/sem/test_helper.h"
+
+#include "src/tint/sem/materialize.h"
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace tint::sem {
+namespace {
+
+using ExpressionTest = TestHelper;
+
+TEST_F(ExpressionTest, UnwrapMaterialize) {
+ auto* a = create<Expression>(/* declaration */ nullptr, create<I32>(), /* statement */ nullptr,
+ Constant{},
+ /* has_side_effects */ false, /* source_var */ nullptr);
+ auto* b = create<Materialize>(a, /* statement */ nullptr, Constant{create<I32>(), {1_a}});
+
+ EXPECT_EQ(a, a->UnwrapMaterialize());
+ EXPECT_EQ(a, b->UnwrapMaterialize());
+}
+
+} // namespace
+} // namespace tint::sem
diff --git a/src/tint/sem/f16.cc b/src/tint/sem/f16.cc
new file mode 100644
index 0000000..7da65fa
--- /dev/null
+++ b/src/tint/sem/f16.cc
@@ -0,0 +1,55 @@
+// 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/f16.h"
+
+#include "src/tint/program_builder.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::sem::F16);
+
+namespace tint {
+namespace sem {
+
+F16::F16() = default;
+
+F16::F16(F16&&) = default;
+
+F16::~F16() = default;
+
+size_t F16::Hash() const {
+ return static_cast<size_t>(TypeInfo::Of<F16>().full_hashcode);
+}
+
+bool F16::Equals(const Type& other) const {
+ return other.Is<F16>();
+}
+
+std::string F16::FriendlyName(const SymbolTable&) const {
+ return "f16";
+}
+
+bool F16::IsConstructible() const {
+ return true;
+}
+
+uint32_t F16::Size() const {
+ return 2;
+}
+
+uint32_t F16::Align() const {
+ return 2;
+}
+
+} // namespace sem
+} // namespace tint
diff --git a/src/tint/sem/f16.h b/src/tint/sem/f16.h
new file mode 100644
index 0000000..72984c1
--- /dev/null
+++ b/src/tint/sem/f16.h
@@ -0,0 +1,58 @@
+// 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_F16_H_
+#define SRC_TINT_SEM_F16_H_
+
+#include <string>
+
+#include "src/tint/sem/type.h"
+
+namespace tint::sem {
+
+/// A float 16 type
+class F16 : public Castable<F16, Type> {
+ public:
+ /// Constructor
+ F16();
+ /// Move constructor
+ F16(F16&&);
+ ~F16() override;
+
+ /// @returns a hash of the type.
+ size_t Hash() const override;
+
+ /// @param other the other type to compare against
+ /// @returns true if the this type is equal to the given type
+ bool Equals(const Type& other) const override;
+
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
+ /// @returns true if constructible as per
+ /// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
+ bool IsConstructible() const override;
+
+ /// @returns the size in bytes of the type.
+ uint32_t Size() const override;
+
+ /// @returns the alignment in bytes of the type.
+ uint32_t Align() const override;
+};
+
+} // namespace tint::sem
+
+#endif // SRC_TINT_SEM_F16_H_
diff --git a/src/tint/sem/f16_test.cc b/src/tint/sem/f16_test.cc
new file mode 100644
index 0000000..28fd0da
--- /dev/null
+++ b/src/tint/sem/f16_test.cc
@@ -0,0 +1,48 @@
+// 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/test_helper.h"
+#include "src/tint/sem/texture.h"
+
+namespace tint::sem {
+namespace {
+
+using F16Test = TestHelper;
+
+TEST_F(F16Test, Creation) {
+ auto* a = create<F16>();
+ auto* b = create<F16>();
+ EXPECT_EQ(a, b);
+}
+
+TEST_F(F16Test, Hash) {
+ auto* a = create<F16>();
+ auto* b = create<F16>();
+ EXPECT_EQ(a->Hash(), b->Hash());
+}
+
+TEST_F(F16Test, Equals) {
+ auto* a = create<F16>();
+ auto* b = create<F16>();
+ EXPECT_TRUE(a->Equals(*b));
+ EXPECT_FALSE(a->Equals(Void{}));
+}
+
+TEST_F(F16Test, FriendlyName) {
+ F16 f;
+ EXPECT_EQ(f.FriendlyName(Symbols()), "f16");
+}
+
+} // namespace
+} // namespace tint::sem
diff --git a/src/tint/sem/materialize.cc b/src/tint/sem/materialize.cc
new file mode 100644
index 0000000..76dd9d4
--- /dev/null
+++ b/src/tint/sem/materialize.cc
@@ -0,0 +1,36 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0(the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/sem/materialize.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::sem::Materialize);
+
+namespace tint::sem {
+
+Materialize::Materialize(const Expression* expr, const Statement* statement, Constant constant)
+ : Base(/* declaration */ expr->Declaration(),
+ /* 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());
+}
+
+Materialize::~Materialize() = default;
+
+} // namespace tint::sem
diff --git a/src/tint/sem/materialize.h b/src/tint/sem/materialize.h
new file mode 100644
index 0000000..a7c0e3a
--- /dev/null
+++ b/src/tint/sem/materialize.h
@@ -0,0 +1,48 @@
+// 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_MATERIALIZE_H_
+#define SRC_TINT_SEM_MATERIALIZE_H_
+
+#include "src/tint/sem/expression.h"
+
+namespace tint::sem {
+
+/// Materialize is a semantic expression which represents the materialization of a value of an
+/// abstract numeric type to a value of a concrete type.
+/// Abstract numeric materialization is implicit in WGSL, so the Materialize semantic node shares
+/// the same AST node as the inner semantic node.
+/// Abstract numerics types may only be used by compile-time expressions, so a Materialize semantic
+/// node must have a valid Constant value.
+class Materialize final : public Castable<Materialize, Expression> {
+ public:
+ /// Constructor
+ /// @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);
+
+ /// Destructor
+ ~Materialize() override;
+
+ /// @return the target of the call
+ const Expression* Expr() const { return expr_; }
+
+ private:
+ Expression const* const expr_;
+};
+
+} // namespace tint::sem
+
+#endif // SRC_TINT_SEM_MATERIALIZE_H_
diff --git a/src/tint/sem/module.cc b/src/tint/sem/module.cc
index 83b7136..7c60650 100644
--- a/src/tint/sem/module.cc
+++ b/src/tint/sem/module.cc
@@ -21,8 +21,8 @@
namespace tint::sem {
-Module::Module(std::vector<const ast::Node*> dep_ordered_decls)
- : dep_ordered_decls_(std::move(dep_ordered_decls)) {}
+Module::Module(std::vector<const ast::Node*> dep_ordered_decls, ast::Extensions extensions)
+ : dep_ordered_decls_(std::move(dep_ordered_decls)), extensions_(std::move(extensions)) {}
Module::~Module() = default;
diff --git a/src/tint/sem/module.h b/src/tint/sem/module.h
index c265d4e..a7b3d45 100644
--- a/src/tint/sem/module.h
+++ b/src/tint/sem/module.h
@@ -17,6 +17,7 @@
#include <vector>
+#include "src/tint/ast/extension.h"
#include "src/tint/sem/node.h"
// Forward declarations
@@ -33,7 +34,8 @@
public:
/// Constructor
/// @param dep_ordered_decls the dependency-ordered module-scope declarations
- explicit Module(std::vector<const ast::Node*> dep_ordered_decls);
+ /// @param extensions the list of enabled extensions in the module
+ Module(std::vector<const ast::Node*> dep_ordered_decls, ast::Extensions extensions);
/// Destructor
~Module() override;
@@ -43,8 +45,12 @@
return dep_ordered_decls_;
}
+ /// @returns the list of enabled extensions in the module
+ const ast::Extensions& Extensions() const { return extensions_; }
+
private:
const std::vector<const ast::Node*> dep_ordered_decls_;
+ ast::Extensions extensions_;
};
} // namespace tint::sem
diff --git a/src/tint/sem/parameter_usage.cc b/src/tint/sem/parameter_usage.cc
index 4891bba..010272a 100644
--- a/src/tint/sem/parameter_usage.cc
+++ b/src/tint/sem/parameter_usage.cc
@@ -56,6 +56,24 @@
return "texture";
case ParameterUsage::kValue:
return "value";
+ case ParameterUsage::kW:
+ return "w";
+ case ParameterUsage::kX:
+ return "x";
+ case ParameterUsage::kXy:
+ return "xy";
+ case ParameterUsage::kXyz:
+ return "xyz";
+ case ParameterUsage::kY:
+ return "y";
+ case ParameterUsage::kYz:
+ return "yz";
+ case ParameterUsage::kZ:
+ return "z";
+ case ParameterUsage::kZw:
+ return "zw";
+ case ParameterUsage::kZyw:
+ return "zyw";
}
return "<unknown>";
}
diff --git a/src/tint/sem/parameter_usage.h b/src/tint/sem/parameter_usage.h
index 85ef64f..b17ae3e 100644
--- a/src/tint/sem/parameter_usage.h
+++ b/src/tint/sem/parameter_usage.h
@@ -44,6 +44,15 @@
kSampler,
kTexture,
kValue,
+ kW,
+ kX,
+ kXy,
+ kXyz,
+ kY,
+ kYz,
+ kZ,
+ kZw,
+ kZyw,
};
/// @returns a string representation of the given parameter usage.
diff --git a/src/tint/sem/switch_statement.h b/src/tint/sem/switch_statement.h
index a5ef659..a6b5c00 100644
--- a/src/tint/sem/switch_statement.h
+++ b/src/tint/sem/switch_statement.h
@@ -15,6 +15,8 @@
#ifndef SRC_TINT_SEM_SWITCH_STATEMENT_H_
#define SRC_TINT_SEM_SWITCH_STATEMENT_H_
+#include <vector>
+
#include "src/tint/sem/block_statement.h"
// Forward declarations
@@ -22,6 +24,10 @@
class CaseStatement;
class SwitchStatement;
} // namespace tint::ast
+namespace tint::sem {
+class CaseStatement;
+class Expression;
+} // namespace tint::sem
namespace tint::sem {
@@ -41,6 +47,15 @@
/// @return the AST node for this statement
const ast::SwitchStatement* Declaration() const;
+
+ /// @returns the case statements for this switch
+ std::vector<const CaseStatement*>& Cases() { return cases_; }
+
+ /// @returns the case statements for this switch
+ const std::vector<const CaseStatement*>& Cases() const { return cases_; }
+
+ private:
+ std::vector<const CaseStatement*> cases_;
};
/// Holds semantic information about a switch case statement
@@ -66,8 +81,15 @@
/// @returns the case body block statement
const BlockStatement* Body() const { return body_; }
+ /// @returns the selectors for the case
+ std::vector<const Expression*>& Selectors() { return selectors_; }
+
+ /// @returns the selectors for the case
+ const std::vector<const Expression*>& Selectors() const { return selectors_; }
+
private:
const BlockStatement* body_ = nullptr;
+ std::vector<const Expression*> selectors_;
};
} // namespace tint::sem
diff --git a/src/tint/sem/test_helper.h b/src/tint/sem/test_helper.h
index 94f66e4..e1b4eb3 100644
--- a/src/tint/sem/test_helper.h
+++ b/src/tint/sem/test_helper.h
@@ -44,4 +44,16 @@
} // namespace tint::sem
+/// Helper macro for testing that a semantic type was as expected
+#define EXPECT_TYPE(GOT, EXPECT) \
+ do { \
+ const sem::Type* got = GOT; \
+ const sem::Type* expect = EXPECT; \
+ if (got != expect) { \
+ ADD_FAILURE() << #GOT " != " #EXPECT "\n" \
+ << " " #GOT ": " << FriendlyName(got) << "\n" \
+ << " " #EXPECT ": " << FriendlyName(expect); \
+ } \
+ } while (false)
+
#endif // SRC_TINT_SEM_TEST_HELPER_H_
diff --git a/src/tint/sem/type.cc b/src/tint/sem/type.cc
index 5776ff4..40666e3 100644
--- a/src/tint/sem/type.cc
+++ b/src/tint/sem/type.cc
@@ -14,7 +14,11 @@
#include "src/tint/sem/type.h"
+#include "src/tint/sem/abstract_float.h"
+#include "src/tint/sem/abstract_int.h"
+#include "src/tint/sem/array.h"
#include "src/tint/sem/bool.h"
+#include "src/tint/sem/f16.h"
#include "src/tint/sem/f32.h"
#include "src/tint/sem/i32.h"
#include "src/tint/sem/matrix.h"
@@ -64,15 +68,19 @@
}
bool Type::is_scalar() const {
- return IsAnyOf<F32, U32, I32, Bool>();
+ return IsAnyOf<F16, F32, U32, I32, Bool>();
+}
+
+bool Type::is_abstract_or_scalar() const {
+ return IsAnyOf<F16, F32, U32, I32, Bool, AbstractNumeric>();
}
bool Type::is_numeric_scalar() const {
- return IsAnyOf<F32, U32, I32>();
+ return IsAnyOf<F16, F32, U32, I32>();
}
bool Type::is_float_scalar() const {
- return Is<F32>();
+ return IsAnyOf<F16, F32>();
}
bool Type::is_float_matrix() const {
@@ -152,4 +160,98 @@
return IsAnyOf<Sampler, Texture>();
}
+uint32_t Type::ConversionRank(const Type* from, const Type* to) {
+ if (from->UnwrapRef() == to) {
+ return 0;
+ }
+ return Switch(
+ from,
+ [&](const AbstractFloat*) {
+ return Switch(
+ to, //
+ [&](const F32*) { return 1; }, //
+ [&](const F16*) { return 2; }, //
+ [&](Default) { return kNoConversion; });
+ },
+ [&](const AbstractInt*) {
+ return Switch(
+ to, //
+ [&](const I32*) { return 3; }, //
+ [&](const U32*) { return 4; }, //
+ [&](const AbstractFloat*) { return 5; }, //
+ [&](const F32*) { return 6; }, //
+ [&](const F16*) { return 7; }, //
+ [&](Default) { return kNoConversion; });
+ },
+ [&](const Vector* from_vec) {
+ if (auto* to_vec = to->As<Vector>()) {
+ if (from_vec->Width() == to_vec->Width()) {
+ return ConversionRank(from_vec->type(), to_vec->type());
+ }
+ }
+ return kNoConversion;
+ },
+ [&](const Matrix* from_mat) {
+ if (auto* to_mat = to->As<Matrix>()) {
+ if (from_mat->columns() == to_mat->columns() &&
+ from_mat->rows() == to_mat->rows()) {
+ return ConversionRank(from_mat->type(), to_mat->type());
+ }
+ }
+ return kNoConversion;
+ },
+ [&](Default) { return kNoConversion; });
+}
+
+const Type* Type::ElementOf(const Type* ty, uint32_t* count /* = nullptr */) {
+ if (ty->is_abstract_or_scalar()) {
+ if (count) {
+ *count = 1;
+ }
+ return ty;
+ }
+ return Switch(
+ ty, //
+ [&](const Vector* v) {
+ if (count) {
+ *count = v->Width();
+ }
+ return v->type();
+ },
+ [&](const Matrix* m) {
+ if (count) {
+ *count = m->columns() * m->rows();
+ }
+ return m->type();
+ },
+ [&](const Array* a) {
+ if (count) {
+ *count = a->Count();
+ }
+ return a->ElemType();
+ });
+}
+
+const sem::Type* Type::Common(Type const* const* types, size_t count) {
+ if (count == 0) {
+ return nullptr;
+ }
+ const auto* common = types[0];
+ for (size_t i = 1; i < count; i++) {
+ auto* ty = types[i];
+ if (ty == common) {
+ continue; // ty == common
+ }
+ if (sem::Type::ConversionRank(ty, common) != sem::Type::kNoConversion) {
+ continue; // ty can be converted to common.
+ }
+ if (sem::Type::ConversionRank(common, ty) != sem::Type::kNoConversion) {
+ common = ty; // common can be converted to ty.
+ continue;
+ }
+ return nullptr; // Conversion is not valid.
+ }
+ return common;
+}
+
} // namespace tint::sem
diff --git a/src/tint/sem/type.h b/src/tint/sem/type.h
index 271e1d7..9987637 100644
--- a/src/tint/sem/type.h
+++ b/src/tint/sem/type.h
@@ -71,6 +71,8 @@
/// @returns true if this type is a scalar
bool is_scalar() const;
+ /// @returns true if this type is a scalar or an abstract numeric
+ bool is_abstract_or_scalar() const;
/// @returns true if this type is a numeric scalar
bool is_numeric_scalar() const;
/// @returns true if this type is a float scalar
@@ -114,6 +116,40 @@
/// @returns true if this type is a handle type
bool is_handle() const;
+ /// kNoConversion is returned from ConversionRank() when the implicit conversion is not
+ /// permitted.
+ static constexpr uint32_t kNoConversion = 0xffffffffu;
+
+ /// ConversionRank returns the implicit conversion rank when attempting to convert `from` to
+ /// `to`. Lower ranks are preferred over higher ranks.
+ /// @param from the source type
+ /// @param to the destination type
+ /// @returns the rank value for converting from type `from` to type `to`, or #kNoConversion if
+ /// the implicit conversion is not allowed.
+ /// @see https://www.w3.org/TR/WGSL/#conversion-rank
+ 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.
+ static const Type* ElementOf(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,
+ /// or nullptr if there is no consistent common type across all types in `types`.
+ /// @see https://www.w3.org/TR/WGSL/#conversion-rank
+ static const sem::Type* Common(Type const* const* types, size_t count);
+
+ /// @param types an initializer_list of `const Type*`.
+ /// @returns the lowest-ranking type that all types in `types` can be implicitly converted to,
+ /// or nullptr if there is no consistent common type across all types in `types`.
+ /// @see https://www.w3.org/TR/WGSL/#conversion-rank
+ static const sem::Type* Common(std::initializer_list<const Type*> types) {
+ return Common(types.begin(), types.size());
+ }
+
protected:
Type();
};
diff --git a/src/tint/sem/type_mappings.h b/src/tint/sem/type_mappings.h
index 8425f14..0e54eed 100644
--- a/src/tint/sem/type_mappings.h
+++ b/src/tint/sem/type_mappings.h
@@ -30,6 +30,7 @@
class Statement;
class Struct;
class StructMember;
+class SwitchStatement;
class Type;
class TypeDecl;
class Variable;
@@ -46,6 +47,7 @@
class Statement;
class Struct;
class StructMember;
+class SwitchStatement;
class Type;
class Variable;
} // namespace tint::sem
@@ -59,7 +61,6 @@
struct TypeMappings {
//! @cond Doxygen_Suppress
Array* operator()(ast::Array*);
- Call* operator()(ast::CallExpression*);
Expression* operator()(ast::Expression*);
ForLoopStatement* operator()(ast::ForLoopStatement*);
Function* operator()(ast::Function*);
@@ -69,6 +70,7 @@
Statement* operator()(ast::Statement*);
Struct* operator()(ast::Struct*);
StructMember* operator()(ast::StructMember*);
+ SwitchStatement* operator()(ast::SwitchStatement*);
Type* operator()(ast::Type*);
Type* operator()(ast::TypeDecl*);
Variable* operator()(ast::Variable*);
diff --git a/src/tint/sem/type_test.cc b/src/tint/sem/type_test.cc
new file mode 100644
index 0000000..c11efea
--- /dev/null
+++ b/src/tint/sem/type_test.cc
@@ -0,0 +1,393 @@
+// 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/abstract_float.h"
+#include "src/tint/sem/abstract_int.h"
+#include "src/tint/sem/reference.h"
+#include "src/tint/sem/test_helper.h"
+
+namespace tint::sem {
+namespace {
+
+using TypeTest = TestHelper;
+
+TEST_F(TypeTest, ConversionRank) {
+ auto* af = create<AbstractFloat>();
+ auto* ai = create<AbstractInt>();
+ auto* f32 = create<F32>();
+ auto* f16 = create<F16>();
+ auto* i32 = create<I32>();
+ auto* u32 = create<U32>();
+ auto* vec3_f32 = create<Vector>(f32, 3u);
+ 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* vec3_af = create<Vector>(af, 3u);
+ auto* vec3_ai = create<Vector>(ai, 3u);
+ auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
+ auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
+ auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
+ auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
+ auto* ref_u32 = create<Reference>(u32, ast::StorageClass::kPrivate, ast::Access::kReadWrite);
+
+ EXPECT_EQ(Type::ConversionRank(i32, i32), 0u);
+ EXPECT_EQ(Type::ConversionRank(f32, f32), 0u);
+ EXPECT_EQ(Type::ConversionRank(u32, u32), 0u);
+ EXPECT_EQ(Type::ConversionRank(vec3_f32, vec3_f32), 0u);
+ EXPECT_EQ(Type::ConversionRank(vec3_f16, vec3_f16), 0u);
+ EXPECT_EQ(Type::ConversionRank(vec4_f32, vec4_f32), 0u);
+ EXPECT_EQ(Type::ConversionRank(vec3_u32, vec3_u32), 0u);
+ EXPECT_EQ(Type::ConversionRank(vec3_i32, vec3_i32), 0u);
+ EXPECT_EQ(Type::ConversionRank(vec3_af, vec3_af), 0u);
+ EXPECT_EQ(Type::ConversionRank(vec3_ai, vec3_ai), 0u);
+ EXPECT_EQ(Type::ConversionRank(mat3x4_f32, mat3x4_f32), 0u);
+ EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat4x3_f32), 0u);
+ EXPECT_EQ(Type::ConversionRank(mat4x3_f16, mat4x3_f16), 0u);
+ EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_af), 0u);
+ EXPECT_EQ(Type::ConversionRank(ref_u32, u32), 0u);
+
+ EXPECT_EQ(Type::ConversionRank(af, f32), 1u);
+ EXPECT_EQ(Type::ConversionRank(vec3_af, vec3_f32), 1u);
+ EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_f32), 1u);
+ EXPECT_EQ(Type::ConversionRank(af, f16), 2u);
+ EXPECT_EQ(Type::ConversionRank(vec3_af, vec3_f16), 2u);
+ EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_f16), 2u);
+ EXPECT_EQ(Type::ConversionRank(ai, i32), 3u);
+ EXPECT_EQ(Type::ConversionRank(vec3_ai, vec3_i32), 3u);
+ EXPECT_EQ(Type::ConversionRank(ai, u32), 4u);
+ EXPECT_EQ(Type::ConversionRank(vec3_ai, vec3_u32), 4u);
+ EXPECT_EQ(Type::ConversionRank(ai, af), 5u);
+ EXPECT_EQ(Type::ConversionRank(ai, f32), 6u);
+ EXPECT_EQ(Type::ConversionRank(ai, f16), 7u);
+
+ EXPECT_EQ(Type::ConversionRank(i32, f32), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(f32, u32), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(u32, i32), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(vec3_u32, vec3_f32), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(vec3_f32, vec4_f32), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(mat3x4_f32, mat4x3_f32), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat3x4_f32), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat4x3_af), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(f32, af), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(f16, af), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(vec3_f16, vec3_af), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(mat4x3_f16, mat4x3_af), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(i32, af), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(u32, af), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(af, ai), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(f32, ai), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(f16, ai), Type::kNoConversion);
+}
+
+TEST_F(TypeTest, ElementOf) {
+ 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* arr_i32 = create<Array>(
+ /* element */ i32,
+ /* count */ 5u,
+ /* align */ 4u,
+ /* size */ 5u * 4u,
+ /* stride */ 5u * 4u,
+ /* implicit_stride */ 5u * 4u);
+
+ // No count
+ EXPECT_TYPE(Type::ElementOf(f32), f32);
+ EXPECT_TYPE(Type::ElementOf(f16), f16);
+ EXPECT_TYPE(Type::ElementOf(i32), i32);
+ EXPECT_TYPE(Type::ElementOf(u32), u32);
+ EXPECT_TYPE(Type::ElementOf(vec2_f32), f32);
+ EXPECT_TYPE(Type::ElementOf(vec3_f16), f16);
+ 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(arr_i32), i32);
+
+ // With count
+ uint32_t count = 0;
+ EXPECT_TYPE(Type::ElementOf(f32, &count), f32);
+ EXPECT_EQ(count, 1u);
+ count = 0;
+ EXPECT_TYPE(Type::ElementOf(f16, &count), f16);
+ EXPECT_EQ(count, 1u);
+ count = 0;
+ EXPECT_TYPE(Type::ElementOf(i32, &count), i32);
+ EXPECT_EQ(count, 1u);
+ count = 0;
+ EXPECT_TYPE(Type::ElementOf(u32, &count), u32);
+ EXPECT_EQ(count, 1u);
+ count = 0;
+ EXPECT_TYPE(Type::ElementOf(vec2_f32, &count), f32);
+ EXPECT_EQ(count, 2u);
+ count = 0;
+ EXPECT_TYPE(Type::ElementOf(vec3_f16, &count), f16);
+ EXPECT_EQ(count, 3u);
+ count = 0;
+ EXPECT_TYPE(Type::ElementOf(vec4_f32, &count), f32);
+ EXPECT_EQ(count, 4u);
+ count = 0;
+ EXPECT_TYPE(Type::ElementOf(vec3_u32, &count), u32);
+ EXPECT_EQ(count, 3u);
+ count = 0;
+ 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;
+ EXPECT_TYPE(Type::ElementOf(arr_i32, &count), i32);
+ EXPECT_EQ(count, 5u);
+}
+
+TEST_F(TypeTest, Common2) {
+ auto* ai = create<AbstractInt>();
+ auto* af = create<AbstractFloat>();
+ auto* f32 = create<F32>();
+ auto* f16 = create<F16>();
+ auto* i32 = create<I32>();
+ auto* u32 = create<U32>();
+
+ EXPECT_TYPE(Type::Common({ai, ai}), ai);
+ EXPECT_TYPE(Type::Common({af, af}), af);
+ EXPECT_TYPE(Type::Common({f32, f32}), f32);
+ EXPECT_TYPE(Type::Common({f16, f16}), f16);
+ EXPECT_TYPE(Type::Common({i32, i32}), i32);
+ EXPECT_TYPE(Type::Common({u32, u32}), u32);
+
+ EXPECT_TYPE(Type::Common({i32, u32}), nullptr);
+ EXPECT_TYPE(Type::Common({u32, f32}), nullptr);
+ EXPECT_TYPE(Type::Common({f32, f16}), nullptr);
+ EXPECT_TYPE(Type::Common({f16, i32}), nullptr);
+
+ EXPECT_TYPE(Type::Common({ai, af}), af);
+ EXPECT_TYPE(Type::Common({ai, f32}), f32);
+ EXPECT_TYPE(Type::Common({ai, f16}), f16);
+ EXPECT_TYPE(Type::Common({ai, i32}), i32);
+ EXPECT_TYPE(Type::Common({ai, u32}), u32);
+
+ EXPECT_TYPE(Type::Common({af, ai}), af);
+ EXPECT_TYPE(Type::Common({f32, ai}), f32);
+ EXPECT_TYPE(Type::Common({f16, ai}), f16);
+ EXPECT_TYPE(Type::Common({i32, ai}), i32);
+ EXPECT_TYPE(Type::Common({u32, ai}), u32);
+
+ EXPECT_TYPE(Type::Common({ai, af}), af);
+ EXPECT_TYPE(Type::Common({f32, af}), f32);
+ EXPECT_TYPE(Type::Common({f16, af}), f16);
+ EXPECT_TYPE(Type::Common({i32, af}), nullptr);
+ EXPECT_TYPE(Type::Common({u32, af}), nullptr);
+
+ EXPECT_TYPE(Type::Common({af, ai}), af);
+ EXPECT_TYPE(Type::Common({af, f32}), f32);
+ EXPECT_TYPE(Type::Common({af, f16}), f16);
+ EXPECT_TYPE(Type::Common({af, i32}), nullptr);
+ EXPECT_TYPE(Type::Common({af, u32}), nullptr);
+
+ auto* vec3_ai = create<Vector>(ai, 3u);
+ auto* vec3_af = create<Vector>(af, 3u);
+ auto* vec3_f32 = create<Vector>(f32, 3u);
+ 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);
+
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_ai}), vec3_ai);
+ EXPECT_TYPE(Type::Common({vec3_af, vec3_af}), vec3_af);
+ EXPECT_TYPE(Type::Common({vec3_f32, vec3_f32}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_f16, vec3_f16}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec4_f32, vec4_f32}), vec4_f32);
+ EXPECT_TYPE(Type::Common({vec3_u32, vec3_u32}), vec3_u32);
+ EXPECT_TYPE(Type::Common({vec3_i32, vec3_i32}), vec3_i32);
+
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_f32}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_f16}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec4_f32}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_u32}), vec3_u32);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_i32}), vec3_i32);
+
+ EXPECT_TYPE(Type::Common({vec3_f32, vec3_ai}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_f16, vec3_ai}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec4_f32, vec3_ai}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_u32, vec3_ai}), vec3_u32);
+ EXPECT_TYPE(Type::Common({vec3_i32, vec3_ai}), vec3_i32);
+
+ EXPECT_TYPE(Type::Common({vec3_af, vec3_f32}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_af, vec3_f16}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec3_af, vec4_f32}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_af, vec3_u32}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_af, vec3_i32}), nullptr);
+
+ EXPECT_TYPE(Type::Common({vec3_f32, vec3_af}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_f16, vec3_af}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec4_f32, vec3_af}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_u32, vec3_af}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_i32, vec3_af}), nullptr);
+
+ auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
+ auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
+ auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
+ auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
+
+ EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_af}), mat4x3_af);
+ EXPECT_TYPE(Type::Common({mat3x4_f32, mat3x4_f32}), mat3x4_f32);
+ EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_f32}), mat4x3_f32);
+ EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_f16}), mat4x3_f16);
+
+ EXPECT_TYPE(Type::Common({mat4x3_af, mat3x4_f32}), nullptr);
+ EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f32}), mat4x3_f32);
+ EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f16}), mat4x3_f16);
+
+ EXPECT_TYPE(Type::Common({mat3x4_f32, mat4x3_af}), nullptr);
+ EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_af}), mat4x3_f32);
+ EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_af}), mat4x3_f16);
+}
+
+TEST_F(TypeTest, Common3) {
+ auto* ai = create<AbstractInt>();
+ auto* af = create<AbstractFloat>();
+ auto* f32 = create<F32>();
+ auto* f16 = create<F16>();
+ auto* i32 = create<I32>();
+ auto* u32 = create<U32>();
+
+ EXPECT_TYPE(Type::Common({ai, ai, ai}), ai);
+ EXPECT_TYPE(Type::Common({af, af, af}), af);
+ EXPECT_TYPE(Type::Common({f32, f32, f32}), f32);
+ EXPECT_TYPE(Type::Common({f16, f16, f16}), f16);
+ EXPECT_TYPE(Type::Common({i32, i32, i32}), i32);
+ EXPECT_TYPE(Type::Common({u32, u32, u32}), u32);
+
+ EXPECT_TYPE(Type::Common({ai, af, ai}), af);
+ EXPECT_TYPE(Type::Common({ai, f32, ai}), f32);
+ EXPECT_TYPE(Type::Common({ai, f16, ai}), f16);
+ EXPECT_TYPE(Type::Common({ai, i32, ai}), i32);
+ EXPECT_TYPE(Type::Common({ai, u32, ai}), u32);
+
+ EXPECT_TYPE(Type::Common({af, ai, af}), af);
+ EXPECT_TYPE(Type::Common({f32, ai, f32}), f32);
+ EXPECT_TYPE(Type::Common({f16, ai, f16}), f16);
+ EXPECT_TYPE(Type::Common({i32, ai, i32}), i32);
+ EXPECT_TYPE(Type::Common({u32, ai, u32}), u32);
+
+ EXPECT_TYPE(Type::Common({ai, f32, ai}), f32);
+ EXPECT_TYPE(Type::Common({ai, f16, ai}), f16);
+ EXPECT_TYPE(Type::Common({ai, i32, ai}), i32);
+ EXPECT_TYPE(Type::Common({ai, u32, ai}), u32);
+
+ EXPECT_TYPE(Type::Common({f32, ai, f32}), f32);
+ EXPECT_TYPE(Type::Common({f16, ai, f16}), f16);
+ EXPECT_TYPE(Type::Common({i32, ai, i32}), i32);
+ EXPECT_TYPE(Type::Common({u32, ai, u32}), u32);
+
+ EXPECT_TYPE(Type::Common({af, f32, af}), f32);
+ EXPECT_TYPE(Type::Common({af, f16, af}), f16);
+ EXPECT_TYPE(Type::Common({af, i32, af}), nullptr);
+ EXPECT_TYPE(Type::Common({af, u32, af}), nullptr);
+
+ EXPECT_TYPE(Type::Common({f32, af, f32}), f32);
+ EXPECT_TYPE(Type::Common({f16, af, f16}), f16);
+ EXPECT_TYPE(Type::Common({i32, af, i32}), nullptr);
+ EXPECT_TYPE(Type::Common({u32, af, u32}), nullptr);
+
+ EXPECT_TYPE(Type::Common({ai, af, f32}), f32);
+ EXPECT_TYPE(Type::Common({ai, af, f16}), f16);
+ EXPECT_TYPE(Type::Common({ai, af, i32}), nullptr);
+ EXPECT_TYPE(Type::Common({ai, af, u32}), nullptr);
+
+ auto* vec3_ai = create<Vector>(ai, 3u);
+ auto* vec3_af = create<Vector>(af, 3u);
+ auto* vec3_f32 = create<Vector>(f32, 3u);
+ 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);
+
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_ai, vec3_ai}), vec3_ai);
+ EXPECT_TYPE(Type::Common({vec3_af, vec3_af, vec3_af}), vec3_af);
+ EXPECT_TYPE(Type::Common({vec3_f32, vec3_f32, vec3_f32}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_f16, vec3_f16, vec3_f16}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec4_f32, vec4_f32, vec4_f32}), vec4_f32);
+ EXPECT_TYPE(Type::Common({vec3_u32, vec3_u32, vec3_u32}), vec3_u32);
+ EXPECT_TYPE(Type::Common({vec3_i32, vec3_i32, vec3_i32}), vec3_i32);
+
+ EXPECT_TYPE(Type::Common({vec3_f32, vec3_ai, vec3_f32}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_f16, vec3_ai, vec3_f16}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec4_f32, vec3_ai, vec4_f32}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_u32, vec3_ai, vec3_u32}), vec3_u32);
+ EXPECT_TYPE(Type::Common({vec3_i32, vec3_ai, vec3_i32}), vec3_i32);
+
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_f32, vec3_ai}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_f16, vec3_ai}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec4_f32, vec3_ai}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_u32, vec3_ai}), vec3_u32);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_i32, vec3_ai}), vec3_i32);
+
+ EXPECT_TYPE(Type::Common({vec3_f32, vec3_af, vec3_f32}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_f16, vec3_af, vec3_f16}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec4_f32, vec3_af, vec4_f32}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_u32, vec3_af, vec3_u32}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_i32, vec3_af, vec3_i32}), nullptr);
+
+ EXPECT_TYPE(Type::Common({vec3_af, vec3_f32, vec3_af}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_af, vec3_f16, vec3_af}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec3_af, vec4_f32, vec3_af}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_af, vec3_u32, vec3_af}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_af, vec3_i32, vec3_af}), nullptr);
+
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_f32}), vec3_f32);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_f16}), vec3_f16);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec4_f32}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_u32}), nullptr);
+ EXPECT_TYPE(Type::Common({vec3_ai, vec3_af, vec3_i32}), nullptr);
+
+ auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
+ auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
+ auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
+ auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
+
+ EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_af, mat4x3_af}), mat4x3_af);
+ EXPECT_TYPE(Type::Common({mat3x4_f32, mat3x4_f32, mat3x4_f32}), mat3x4_f32);
+ EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_f32, mat4x3_f32}), mat4x3_f32);
+ EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_f16, mat4x3_f16}), mat4x3_f16);
+
+ EXPECT_TYPE(Type::Common({mat3x4_f32, mat4x3_af, mat3x4_f32}), nullptr);
+ EXPECT_TYPE(Type::Common({mat4x3_f32, mat4x3_af, mat4x3_f32}), mat4x3_f32);
+ EXPECT_TYPE(Type::Common({mat4x3_f16, mat4x3_af, mat4x3_f16}), mat4x3_f16);
+
+ EXPECT_TYPE(Type::Common({mat4x3_af, mat3x4_f32, mat4x3_af}), nullptr);
+ EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f32, mat4x3_af}), mat4x3_f32);
+ EXPECT_TYPE(Type::Common({mat4x3_af, mat4x3_f16, mat4x3_af}), mat4x3_f16);
+}
+
+} // namespace
+} // namespace tint::sem
diff --git a/src/tint/sem/vector.cc b/src/tint/sem/vector.cc
index 6b4e15d..2df7cf0 100644
--- a/src/tint/sem/vector.cc
+++ b/src/tint/sem/vector.cc
@@ -52,33 +52,17 @@
}
uint32_t Vector::Size() const {
- return SizeOf(width_);
+ return subtype_->Size() * width_;
}
uint32_t Vector::Align() const {
- return AlignOf(width_);
-}
-
-uint32_t Vector::SizeOf(uint32_t width) {
- switch (width) {
+ switch (width_) {
case 2:
- return 8;
+ return subtype_->Size() * 2;
case 3:
- return 12;
+ return subtype_->Size() * 4;
case 4:
- return 16;
- }
- return 0; // Unreachable
-}
-
-uint32_t Vector::AlignOf(uint32_t width) {
- switch (width) {
- case 2:
- return 8;
- case 3:
- return 16;
- case 4:
- return 16;
+ return subtype_->Size() * 4;
}
return 0; // Unreachable
}
diff --git a/src/tint/symbol_table.cc b/src/tint/symbol_table.cc
index 0a7fa5c..2b20fed 100644
--- a/src/tint/symbol_table.cc
+++ b/src/tint/symbol_table.cc
@@ -34,8 +34,9 @@
TINT_ASSERT(Symbol, !name.empty());
auto it = name_to_symbol_.find(name);
- if (it != name_to_symbol_.end())
+ if (it != name_to_symbol_.end()) {
return it->second;
+ }
#if TINT_SYMBOL_STORE_DEBUG_NAME
Symbol sym(next_symbol_, program_id_, name);
diff --git a/src/tint/transform/array_length_from_uniform.cc b/src/tint/transform/array_length_from_uniform.cc
index dc19c5c..86c4534 100644
--- a/src/tint/transform/array_length_from_uniform.cc
+++ b/src/tint/transform/array_length_from_uniform.cc
@@ -52,7 +52,7 @@
continue;
}
- auto* call = sem.Get(call_expr);
+ auto* call = sem.Get(call_expr)->UnwrapMaterialize()->As<sem::Call>();
auto* builtin = call->Target()->As<sem::Builtin>();
if (!builtin || builtin->Type() != sem::BuiltinType::kArrayLength) {
continue;
diff --git a/src/tint/transform/calculate_array_length.cc b/src/tint/transform/calculate_array_length.cc
index 42a212c..bdda1cd 100644
--- a/src/tint/transform/calculate_array_length.cc
+++ b/src/tint/transform/calculate_array_length.cc
@@ -123,7 +123,7 @@
// Find all the arrayLength() calls...
for (auto* node : ctx.src->ASTNodes().Objects()) {
if (auto* call_expr = node->As<ast::CallExpression>()) {
- auto* call = sem.Get(call_expr);
+ auto* call = sem.Get(call_expr)->UnwrapMaterialize()->As<sem::Call>();
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
if (builtin->Type() == sem::BuiltinType::kArrayLength) {
// We're dealing with an arrayLength() call
diff --git a/src/tint/transform/combine_samplers.cc b/src/tint/transform/combine_samplers.cc
index 66b5b93..c9d4913 100644
--- a/src/tint/transform/combine_samplers.cc
+++ b/src/tint/transform/combine_samplers.cc
@@ -220,7 +220,7 @@
// sampler parameters to use the current function's combined samplers or
// the combined global samplers, as appropriate.
ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::Expression* {
- if (auto* call = sem.Get(expr)) {
+ if (auto* call = sem.Get(expr)->UnwrapMaterialize()->As<sem::Call>()) {
ast::ExpressionList args;
// Replace all texture builtin calls.
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc
index 66c6073..775cc05 100644
--- a/src/tint/transform/decompose_memory_access.cc
+++ b/src/tint/transform/decompose_memory_access.cc
@@ -882,7 +882,7 @@
}
if (auto* call_expr = node->As<ast::CallExpression>()) {
- auto* call = sem.Get(call_expr);
+ auto* call = sem.Get(call_expr)->UnwrapMaterialize()->As<sem::Call>();
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
if (builtin->Type() == sem::BuiltinType::kArrayLength) {
// arrayLength(X)
diff --git a/src/tint/transform/decompose_strided_array.cc b/src/tint/transform/decompose_strided_array.cc
index bf36c06..ba6252b 100644
--- a/src/tint/transform/decompose_strided_array.cc
+++ b/src/tint/transform/decompose_strided_array.cc
@@ -115,7 +115,7 @@
// `array<strided_arr, 3>(strided_arr(1), strided_arr(2), strided_arr(3))`
ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::Expression* {
if (!expr->args.empty()) {
- if (auto* call = sem.Get(expr)) {
+ if (auto* call = sem.Get(expr)->UnwrapMaterialize()->As<sem::Call>()) {
if (auto* ctor = call->Target()->As<sem::TypeConstructor>()) {
if (auto* arr = ctor->ReturnType()->As<sem::Array>()) {
// Begin by cloning the array constructor type or name
diff --git a/src/tint/transform/disable_uniformity_analysis.cc b/src/tint/transform/disable_uniformity_analysis.cc
new file mode 100644
index 0000000..7a30023
--- /dev/null
+++ b/src/tint/transform/disable_uniformity_analysis.cc
@@ -0,0 +1,40 @@
+// 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/disable_uniformity_analysis.h"
+
+#include <utility>
+
+#include "src/tint/program_builder.h"
+#include "src/tint/sem/module.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::transform::DisableUniformityAnalysis);
+
+namespace tint::transform {
+
+DisableUniformityAnalysis::DisableUniformityAnalysis() = default;
+
+DisableUniformityAnalysis::~DisableUniformityAnalysis() = default;
+
+bool DisableUniformityAnalysis::ShouldRun(const Program* program, const DataMap&) const {
+ return !program->Sem().Module()->Extensions().contains(
+ ast::Extension::kChromiumDisableUniformityAnalysis);
+}
+
+void DisableUniformityAnalysis::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+ ctx.dst->Enable(ast::Extension::kChromiumDisableUniformityAnalysis);
+ ctx.Clone();
+}
+
+} // namespace tint::transform
diff --git a/src/tint/transform/disable_uniformity_analysis.h b/src/tint/transform/disable_uniformity_analysis.h
new file mode 100644
index 0000000..3c9fb53
--- /dev/null
+++ b/src/tint/transform/disable_uniformity_analysis.h
@@ -0,0 +1,47 @@
+// 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_DISABLE_UNIFORMITY_ANALYSIS_H_
+#define SRC_TINT_TRANSFORM_DISABLE_UNIFORMITY_ANALYSIS_H_
+
+#include "src/tint/transform/transform.h"
+
+namespace tint::transform {
+
+/// Disable uniformity analysis for the program.
+class DisableUniformityAnalysis final : public Castable<DisableUniformityAnalysis, Transform> {
+ public:
+ /// Constructor
+ DisableUniformityAnalysis();
+ /// Destructor
+ ~DisableUniformityAnalysis() override;
+
+ /// @param program the program to inspect
+ /// @param data optional extra transform-specific input data
+ /// @returns true if this transform should be run for the given program
+ bool ShouldRun(const Program* program, const DataMap& data = {}) const override;
+
+ protected:
+ /// Runs the transform using the CloneContext built for transforming a
+ /// program. Run() is responsible for calling Clone() on the CloneContext.
+ /// @param ctx the CloneContext primed with the input program and
+ /// ProgramBuilder
+ /// @param inputs optional extra transform-specific input data
+ /// @param outputs optional extra transform-specific output data
+ void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) const override;
+};
+
+} // namespace tint::transform
+
+#endif // SRC_TINT_TRANSFORM_DISABLE_UNIFORMITY_ANALYSIS_H_
diff --git a/src/tint/transform/disable_uniformity_analysis_test.cc b/src/tint/transform/disable_uniformity_analysis_test.cc
new file mode 100644
index 0000000..a502442
--- /dev/null
+++ b/src/tint/transform/disable_uniformity_analysis_test.cc
@@ -0,0 +1,73 @@
+// 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/disable_uniformity_analysis.h"
+
+#include <string>
+#include <utility>
+
+#include "src/tint/transform/test_helper.h"
+
+namespace tint::transform {
+namespace {
+
+using DisableUniformityAnalysisTest = TransformTest;
+
+TEST_F(DisableUniformityAnalysisTest, ShouldRunEmptyModule) {
+ auto* src = R"()";
+
+ EXPECT_TRUE(ShouldRun<DisableUniformityAnalysis>(src));
+}
+
+TEST_F(DisableUniformityAnalysisTest, ShouldRunExtensionAlreadyPresent) {
+ auto* src = R"(
+enable chromium_disable_uniformity_analysis;
+)";
+
+ EXPECT_FALSE(ShouldRun<DisableUniformityAnalysis>(src));
+}
+
+TEST_F(DisableUniformityAnalysisTest, EmptyModule) {
+ auto* src = R"()";
+
+ auto* expect = R"(
+enable chromium_disable_uniformity_analysis;
+)";
+
+ auto got = Run<DisableUniformityAnalysis>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DisableUniformityAnalysisTest, NonEmptyModule) {
+ auto* src = R"(
+@group(0) @binding(0) var<storage, read> global : i32;
+
+@stage(compute) @workgroup_size(64)
+fn main() {
+ if ((global == 42)) {
+ workgroupBarrier();
+ }
+}
+)";
+
+ auto expect = "\nenable chromium_disable_uniformity_analysis;\n" + std::string(src);
+
+ auto got = Run<DisableUniformityAnalysis>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace
+} // namespace tint::transform
diff --git a/src/tint/transform/fold_constants.cc b/src/tint/transform/fold_constants.cc
index be547b1..d51a68a 100644
--- a/src/tint/transform/fold_constants.cc
+++ b/src/tint/transform/fold_constants.cc
@@ -56,6 +56,21 @@
return nullptr;
}
+ auto build_scalar = [&](sem::Constant::Scalar s) {
+ return Switch(
+ value.ElementType(), //
+ [&](const sem::I32*) { return ctx.dst->Expr(i32(std::get<AInt>(s).value)); },
+ [&](const sem::U32*) { return ctx.dst->Expr(u32(std::get<AInt>(s).value)); },
+ [&](const sem::F32*) { return ctx.dst->Expr(f32(std::get<AFloat>(s).value)); },
+ [&](const sem::Bool*) { return ctx.dst->Expr(std::get<bool>(s)); },
+ [&](Default) {
+ TINT_ICE(Transform, ctx.dst->Diagnostics())
+ << "unhandled Constant::Scalar type: "
+ << value.ElementType()->FriendlyName(ctx.src->Symbols());
+ return nullptr;
+ });
+ };
+
if (auto* vec = ty->As<sem::Vector>()) {
uint32_t vec_size = static_cast<uint32_t>(vec->Width());
@@ -73,7 +88,7 @@
ast::ExpressionList ctors;
for (uint32_t i = 0; i < ctor_size; ++i) {
- value.WithScalarAt(i, [&](auto&& s) { ctors.emplace_back(ctx.dst->Expr(s)); });
+ ctors.emplace_back(build_scalar(value.Elements()[i]));
}
auto* el_ty = CreateASTTypeFor(ctx, vec->type());
@@ -81,8 +96,7 @@
}
if (ty->is_scalar()) {
- return value.WithScalarAt(
- 0, [&](auto&& s) -> const ast::LiteralExpression* { return ctx.dst->Expr(s); });
+ return build_scalar(value.Elements()[0]);
}
return nullptr;
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index 0bc507e..2a9e20e 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -184,7 +184,8 @@
// Transform the original textureLoad and textureSampleLevel calls into
// textureLoadExternal and textureSampleExternal calls.
ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::CallExpression* {
- auto* builtin = sem.Get(expr)->Target()->As<sem::Builtin>();
+ auto* call = sem.Get(expr)->UnwrapMaterialize()->As<sem::Call>();
+ auto* builtin = call->Target()->As<sem::Builtin>();
if (builtin && !builtin->Parameters().empty() &&
builtin->Parameters()[0]->Type()->Is<sem::ExternalTexture>() &&
@@ -209,7 +210,7 @@
}
}
- } else if (sem.Get(expr)->Target()->Is<sem::Function>()) {
+ } else if (call->Target()->Is<sem::Function>()) {
// The call expression may be to a user-defined function that
// contains a texture_external parameter. These need to be expanded
// out to multiple plane textures and the texture parameters
diff --git a/src/tint/transform/promote_initializers_to_const_var.cc b/src/tint/transform/promote_initializers_to_const_var.cc
index 81b5603..6e0ba55 100644
--- a/src/tint/transform/promote_initializers_to_const_var.cc
+++ b/src/tint/transform/promote_initializers_to_const_var.cc
@@ -33,7 +33,7 @@
// 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);
+ auto* ctor = ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
if (!ctor->Target()->Is<sem::TypeConstructor>()) {
return true;
}
diff --git a/src/tint/transform/remove_phonies.cc b/src/tint/transform/remove_phonies.cc
index dc5c092..7ca1194 100644
--- a/src/tint/transform/remove_phonies.cc
+++ b/src/tint/transform/remove_phonies.cc
@@ -86,12 +86,19 @@
if (stmt->lhs->Is<ast::PhonyExpression>()) {
std::vector<const ast::Expression*> side_effects;
if (!ast::TraverseExpressions(
- stmt->rhs, ctx.dst->Diagnostics(), [&](const ast::CallExpression* call) {
+ stmt->rhs, ctx.dst->Diagnostics(), [&](const ast::CallExpression* expr) {
// ast::CallExpression may map to a function or builtin call
// (both may have side-effects), or a type constructor or
// type conversion (both do not have side effects).
- if (sem.Get(call)->Target()->IsAnyOf<sem::Function, sem::Builtin>()) {
- side_effects.push_back(call);
+ auto* call = sem.Get<sem::Call>(expr);
+ if (!call) {
+ // Semantic node must be a Materialize, in which case the expression
+ // was creation-time (compile time), so could not have side effects.
+ // Just skip.
+ return ast::TraverseAction::Skip;
+ }
+ if (call->Target()->IsAnyOf<sem::Function, sem::Builtin>()) {
+ side_effects.push_back(expr);
return ast::TraverseAction::Skip;
}
return ast::TraverseAction::Descend;
diff --git a/src/tint/transform/renamer.cc b/src/tint/transform/renamer.cc
index 50cd781..562a52f 100644
--- a/src/tint/transform/renamer.cc
+++ b/src/tint/transform/renamer.cc
@@ -1278,7 +1278,7 @@
}
}
} else if (auto* call = node->As<ast::CallExpression>()) {
- auto* sem = in->Sem().Get(call);
+ auto* sem = in->Sem().Get(call)->UnwrapMaterialize()->As<sem::Call>();
if (!sem) {
TINT_ICE(Transform, out.Diagnostics()) << "CallExpression has no semantic info";
continue;
diff --git a/src/tint/transform/robustness.cc b/src/tint/transform/robustness.cc
index a7f2a4a..aab1e0c 100644
--- a/src/tint/transform/robustness.cc
+++ b/src/tint/transform/robustness.cc
@@ -123,10 +123,10 @@
if (auto idx_constant = idx_sem->ConstantValue()) {
// Constant value index
if (idx_constant.Type()->Is<sem::I32>()) {
- idx.i32 = idx_constant.Elements()[0].i32;
+ idx.i32 = static_cast<int32_t>(idx_constant.Element<AInt>(0).value);
idx.is_signed = true;
} else if (idx_constant.Type()->Is<sem::U32>()) {
- idx.u32 = idx_constant.Elements()[0].u32;
+ idx.u32 = static_cast<uint32_t>(idx_constant.Element<AInt>(0).value);
idx.is_signed = false;
} else {
TINT_ICE(Transform, b.Diagnostics()) << "unsupported constant value for accessor "
@@ -206,7 +206,7 @@
/// @return the clamped replacement call expression, or nullptr if `expr`
/// should be cloned without changes.
const ast::CallExpression* Transform(const ast::CallExpression* expr) {
- auto* call = ctx.src->Sem().Get(expr);
+ auto* call = ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
auto* call_target = call->Target();
auto* builtin = call_target->As<sem::Builtin>();
if (!builtin || !TextureBuiltinNeedsClamping(builtin->Type())) {
diff --git a/src/tint/transform/transform.cc b/src/tint/transform/transform.cc
index e3d0ea9..f3ab173 100644
--- a/src/tint/transform/transform.cc
+++ b/src/tint/transform/transform.cc
@@ -87,6 +87,9 @@
if (ty->Is<sem::U32>()) {
return ctx.dst->create<ast::U32>();
}
+ if (ty->Is<sem::F16>()) {
+ return ctx.dst->create<ast::F16>();
+ }
if (ty->Is<sem::F32>()) {
return ctx.dst->create<ast::F32>();
}
diff --git a/src/tint/transform/vectorize_scalar_matrix_constructors.cc b/src/tint/transform/vectorize_scalar_matrix_constructors.cc
index 80e8b1e..9cd9757 100644
--- a/src/tint/transform/vectorize_scalar_matrix_constructors.cc
+++ b/src/tint/transform/vectorize_scalar_matrix_constructors.cc
@@ -14,12 +14,14 @@
#include "src/tint/transform/vectorize_scalar_matrix_constructors.h"
+#include <unordered_map>
#include <utility>
#include "src/tint/program_builder.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"
TINT_INSTANTIATE_TYPEINFO(tint::transform::VectorizeScalarMatrixConstructors);
@@ -44,8 +46,10 @@
}
void VectorizeScalarMatrixConstructors::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
+ std::unordered_map<const sem::Matrix*, Symbol> scalar_ctors;
+
ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::CallExpression* {
- auto* call = ctx.src->Sem().Get(expr);
+ auto* call = ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
auto* ty_ctor = call->Target()->As<sem::TypeConstructor>();
if (!ty_ctor) {
return nullptr;
@@ -64,21 +68,56 @@
return nullptr;
}
- // Build a list of vector expressions for each column.
- ast::ExpressionList columns;
- for (uint32_t c = 0; c < mat_type->columns(); c++) {
- // Build a list of scalar expressions for each value in the column.
- ast::ExpressionList row_values;
- for (uint32_t r = 0; r < mat_type->rows(); r++) {
- row_values.push_back(ctx.Clone(args[c * mat_type->rows() + r]->Declaration()));
- }
+ // Constructs a matrix using vector columns, with the elements constructed using the
+ // 'element(uint32_t c, uint32_t r)' callback.
+ auto build_mat = [&](auto&& element) {
+ ast::ExpressionList columns(mat_type->columns());
+ for (uint32_t c = 0; c < mat_type->columns(); c++) {
+ ast::ExpressionList row_values(mat_type->rows());
+ for (uint32_t r = 0; r < mat_type->rows(); r++) {
+ row_values[r] = element(c, r);
+ }
- // Construct the column vector.
- auto* col =
- ctx.dst->vec(CreateASTTypeFor(ctx, mat_type->type()), mat_type->rows(), row_values);
- columns.push_back(col);
+ // Construct the column vector.
+ columns[c] = ctx.dst->vec(CreateASTTypeFor(ctx, mat_type->type()), mat_type->rows(),
+ row_values);
+ }
+ return ctx.dst->Construct(CreateASTTypeFor(ctx, mat_type), columns);
+ };
+
+ if (args.size() == 1) {
+ // Generate a helper function for constructing the matrix.
+ // This is done to ensure that the single argument value is only evaluated once, and
+ // with the correct expression evaluation order.
+ auto fn = utils::GetOrCreate(scalar_ctors, mat_type, [&] {
+ auto name =
+ ctx.dst->Symbols().New("build_mat" + std::to_string(mat_type->columns()) + "x" +
+ std::to_string(mat_type->rows()));
+ ctx.dst->Func(name,
+ {
+ // Single scalar parameter
+ ctx.dst->Param("value", CreateASTTypeFor(ctx, mat_type->type())),
+ },
+ CreateASTTypeFor(ctx, mat_type),
+ {
+ ctx.dst->Return(build_mat([&](uint32_t, uint32_t) { //
+ return ctx.dst->Expr("value");
+ })),
+ });
+ return name;
+ });
+ return ctx.dst->Call(fn, ctx.Clone(args[0]->Declaration()));
}
- return ctx.dst->Construct(CreateASTTypeFor(ctx, mat_type), columns);
+
+ if (args.size() == mat_type->columns() * mat_type->rows()) {
+ return build_mat([&](uint32_t c, uint32_t r) {
+ return ctx.Clone(args[c * mat_type->rows() + r]->Declaration());
+ });
+ }
+
+ TINT_ICE(Transform, ctx.dst->Diagnostics())
+ << "matrix constructor has unexpected number of arguments";
+ return nullptr;
});
ctx.Clone();
diff --git a/src/tint/transform/vectorize_scalar_matrix_constructors_test.cc b/src/tint/transform/vectorize_scalar_matrix_constructors_test.cc
index 242151a..2b1c098 100644
--- a/src/tint/transform/vectorize_scalar_matrix_constructors_test.cc
+++ b/src/tint/transform/vectorize_scalar_matrix_constructors_test.cc
@@ -31,7 +31,57 @@
EXPECT_FALSE(ShouldRun<VectorizeScalarMatrixConstructors>(src));
}
-TEST_P(VectorizeScalarMatrixConstructorsTest, Basic) {
+TEST_P(VectorizeScalarMatrixConstructorsTest, SingleScalars) {
+ uint32_t cols = GetParam().first;
+ uint32_t rows = GetParam().second;
+ std::string matrix_no_type = "mat" + std::to_string(cols) + "x" + std::to_string(rows);
+ std::string matrix = matrix_no_type + "<f32>";
+ std::string vector = "vec" + std::to_string(rows) + "<f32>";
+ std::string values;
+ for (uint32_t c = 0; c < cols; c++) {
+ if (c > 0) {
+ values += ", ";
+ }
+ values += vector + "(";
+ for (uint32_t r = 0; r < rows; r++) {
+ if (r > 0) {
+ values += ", ";
+ }
+ values += "value";
+ }
+ values += ")";
+ }
+
+ std::string src = R"(
+@stage(fragment)
+fn main() {
+ let m = ${matrix}(42.0);
+}
+)";
+
+ std::string expect = R"(
+fn build_${matrix_no_type}(value : f32) -> ${matrix} {
+ return ${matrix}(${values});
+}
+
+@stage(fragment)
+fn main() {
+ let m = build_${matrix_no_type}(42.0);
+}
+)";
+ src = utils::ReplaceAll(src, "${matrix}", matrix);
+ expect = utils::ReplaceAll(expect, "${matrix}", matrix);
+ expect = utils::ReplaceAll(expect, "${matrix_no_type}", matrix_no_type);
+ expect = utils::ReplaceAll(expect, "${values}", values);
+
+ EXPECT_TRUE(ShouldRun<VectorizeScalarMatrixConstructors>(src));
+
+ auto got = Run<VectorizeScalarMatrixConstructors>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_P(VectorizeScalarMatrixConstructorsTest, MultipleScalars) {
uint32_t cols = GetParam().first;
uint32_t rows = GetParam().second;
std::string mat_type = "mat" + std::to_string(cols) + "x" + std::to_string(rows) + "<f32>";
diff --git a/src/tint/transform/wrap_arrays_in_structs.cc b/src/tint/transform/wrap_arrays_in_structs.cc
index b1dc5e8..eb133d7 100644
--- a/src/tint/transform/wrap_arrays_in_structs.cc
+++ b/src/tint/transform/wrap_arrays_in_structs.cc
@@ -83,7 +83,7 @@
// 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)) {
+ 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)) {
diff --git a/src/tint/transform/zero_init_workgroup_memory.cc b/src/tint/transform/zero_init_workgroup_memory.cc
index 21a4565..6e84310 100644
--- a/src/tint/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/transform/zero_init_workgroup_memory.cc
@@ -359,13 +359,8 @@
}
auto* sem = ctx.src->Sem().Get(expr);
if (auto c = sem->ConstantValue()) {
- if (c.ElementType()->Is<sem::I32>()) {
- workgroup_size_const *= static_cast<uint32_t>(c.Elements()[0].i32);
- continue;
- } else if (c.ElementType()->Is<sem::U32>()) {
- workgroup_size_const *= c.Elements()[0].u32;
- continue;
- }
+ workgroup_size_const *= c.Element<AInt>(0).value;
+ continue;
}
// Constant value could not be found. Build expression instead.
workgroup_size_expr = [this, expr, size = workgroup_size_expr] {
diff --git a/src/tint/utils/hash.h b/src/tint/utils/hash.h
index 1bc2edb..3deb14b 100644
--- a/src/tint/utils/hash.h
+++ b/src/tint/utils/hash.h
@@ -18,6 +18,7 @@
#include <stdint.h>
#include <cstdio>
#include <functional>
+#include <tuple>
#include <utility>
#include <vector>
@@ -45,6 +46,10 @@
} // namespace detail
+// Forward declaration
+template <typename... ARGS>
+size_t Hash(const ARGS&... args);
+
/// HashCombine "hashes" together an existing hash and hashable values.
template <typename T>
void HashCombine(size_t* hash, const T& value) {
@@ -62,6 +67,13 @@
}
/// HashCombine "hashes" together an existing hash and hashable values.
+template <typename... TYPES>
+void HashCombine(size_t* hash, const std::tuple<TYPES...>& tuple) {
+ HashCombine(hash, sizeof...(TYPES));
+ HashCombine(hash, std::apply(Hash<TYPES...>, tuple));
+}
+
+/// HashCombine "hashes" together an existing hash and hashable values.
template <typename T, typename... ARGS>
void HashCombine(size_t* hash, const T& value, const ARGS&... args) {
HashCombine(hash, value);
diff --git a/src/tint/utils/hash_test.cc b/src/tint/utils/hash_test.cc
index 068ac45..cb74df9 100644
--- a/src/tint/utils/hash_test.cc
+++ b/src/tint/utils/hash_test.cc
@@ -15,6 +15,7 @@
#include "src/tint/utils/hash.h"
#include <string>
+#include <tuple>
#include <unordered_map>
#include "gtest/gtest.h"
@@ -41,6 +42,13 @@
EXPECT_NE(Hash(std::vector<int>({1, 2, 3})), Hash(std::vector<int>({1, 2, 3, 4})));
}
+TEST(HashTests, Tuple) {
+ EXPECT_EQ(Hash(std::make_tuple(1)), Hash(std::make_tuple(1)));
+ EXPECT_EQ(Hash(std::make_tuple(1, 2, 3)), Hash(std::make_tuple(1, 2, 3)));
+ EXPECT_NE(Hash(std::make_tuple(1, 2, 3)), Hash(std::make_tuple(1, 2, 4)));
+ EXPECT_NE(Hash(std::make_tuple(1, 2, 3)), Hash(std::make_tuple(1, 2, 3, 4)));
+}
+
TEST(HashTests, UnorderedKeyWrapper) {
using W = UnorderedKeyWrapper<std::vector<int>>;
diff --git a/src/tint/utils/unique_vector.h b/src/tint/utils/unique_vector.h
index 96d9cbf..0f3f18d 100644
--- a/src/tint/utils/unique_vector.h
+++ b/src/tint/utils/unique_vector.h
@@ -75,6 +75,9 @@
/// @returns the number of items in the vector
size_t size() const { return vector.size(); }
+ /// @returns the pointer to the first element in the vector, or nullptr if the vector is empty.
+ const T* data() const { return vector.empty() ? nullptr : vector.data(); }
+
/// @returns an iterator to the beginning of the vector
ConstIterator begin() const { return vector.begin(); }
diff --git a/src/tint/utils/unique_vector_test.cc b/src/tint/utils/unique_vector_test.cc
index 7d586e9..035ebf8 100644
--- a/src/tint/utils/unique_vector_test.cc
+++ b/src/tint/utils/unique_vector_test.cc
@@ -139,5 +139,14 @@
EXPECT_EQ(unique_vec.empty(), true);
}
+TEST(UniqueVectorTest, Data) {
+ UniqueVector<int> unique_vec;
+ EXPECT_EQ(unique_vec.data(), nullptr);
+
+ unique_vec.add(42);
+ EXPECT_EQ(unique_vec.data(), &unique_vec[0]);
+ EXPECT_EQ(*unique_vec.data(), 42);
+}
+
} // namespace
} // namespace tint::utils
diff --git a/src/tint/writer/append_vector_test.cc b/src/tint/writer/append_vector_test.cc
index 46a135f..8169039 100644
--- a/src/tint/writer/append_vector_test.cc
+++ b/src/tint/writer/append_vector_test.cc
@@ -46,7 +46,7 @@
EXPECT_EQ(vec_123->args[1], scalar_2);
EXPECT_EQ(vec_123->args[2], scalar_3);
- auto* call = Sem().Get(vec_123);
+ auto* call = Sem().Get<sem::Call>(vec_123);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 3u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1));
@@ -90,7 +90,7 @@
ASSERT_EQ(u32_to_i32->args.size(), 1u);
EXPECT_EQ(u32_to_i32->args[0], scalar_3);
- auto* call = Sem().Get(vec_123);
+ auto* call = Sem().Get<sem::Call>(vec_123);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 3u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1));
@@ -142,7 +142,7 @@
ASSERT_EQ(u32_to_i32->args.size(), 1u);
EXPECT_EQ(u32_to_i32->args[0], scalar_3);
- auto* call = Sem().Get(vec_123);
+ auto* call = Sem().Get<sem::Call>(vec_123);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 2u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12));
@@ -184,7 +184,7 @@
ASSERT_EQ(f32_to_i32->args.size(), 1u);
EXPECT_EQ(f32_to_i32->args[0], scalar_3);
- auto* call = Sem().Get(vec_123);
+ auto* call = Sem().Get<sem::Call>(vec_123);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 3u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1));
@@ -226,7 +226,7 @@
EXPECT_EQ(vec_1234->args[2], scalar_3);
EXPECT_EQ(vec_1234->args[3], scalar_4);
- auto* call = Sem().Get(vec_1234);
+ auto* call = Sem().Get<sem::Call>(vec_1234);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 4u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1));
@@ -266,7 +266,7 @@
EXPECT_EQ(vec_123->args[0], vec_12);
EXPECT_EQ(vec_123->args[1], scalar_3);
- auto* call = Sem().Get(vec_123);
+ auto* call = Sem().Get<sem::Call>(vec_123);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 2u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12));
@@ -305,7 +305,7 @@
EXPECT_EQ(vec_123->args[1], scalar_2);
EXPECT_EQ(vec_123->args[2], scalar_3);
- auto* call = Sem().Get(vec_123);
+ auto* call = Sem().Get<sem::Call>(vec_123);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 3u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1));
@@ -344,7 +344,7 @@
EXPECT_EQ(vec_123->args[0], vec_12);
EXPECT_EQ(vec_123->args[1], scalar_3);
- auto* call = Sem().Get(vec_123);
+ auto* call = Sem().Get<sem::Call>(vec_123);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 2u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12));
@@ -385,7 +385,7 @@
ASSERT_EQ(f32_to_i32->args.size(), 1u);
EXPECT_EQ(f32_to_i32->args[0], scalar_3);
- auto* call = Sem().Get(vec_123);
+ auto* call = Sem().Get<sem::Call>(vec_123);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 2u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12));
@@ -422,7 +422,7 @@
EXPECT_EQ(vec_123->args[0], vec_12);
EXPECT_EQ(vec_123->args[1], scalar_3);
- auto* call = Sem().Get(vec_123);
+ auto* call = Sem().Get<sem::Call>(vec_123);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 2u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12));
@@ -461,7 +461,7 @@
}
EXPECT_EQ(vec_0004->args[3], scalar);
- auto* call = Sem().Get(vec_0004);
+ auto* call = Sem().Get<sem::Call>(vec_0004);
ASSERT_NE(call, nullptr);
ASSERT_EQ(call->Arguments().size(), 4u);
EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_0004->args[0]));
diff --git a/src/tint/writer/glsl/generator.cc b/src/tint/writer/glsl/generator.cc
index 4b6da68..4b1e516 100644
--- a/src/tint/writer/glsl/generator.cc
+++ b/src/tint/writer/glsl/generator.cc
@@ -30,6 +30,10 @@
Result Generate(const Program* program, const Options& options, const std::string& entry_point) {
Result result;
+ if (!program->IsValid()) {
+ result.error = "input program is not valid";
+ return result;
+ }
// Sanitize the program.
auto sanitized_result = Sanitize(program, options, entry_point);
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index f52862b..1cf7480 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -35,6 +35,7 @@
#include "src/tint/sem/depth_multisampled_texture.h"
#include "src/tint/sem/depth_texture.h"
#include "src/tint/sem/function.h"
+#include "src/tint/sem/materialize.h"
#include "src/tint/sem/member_accessor_expression.h"
#include "src/tint/sem/module.h"
#include "src/tint/sem/multisampled_texture.h"
@@ -52,6 +53,7 @@
#include "src/tint/transform/canonicalize_entry_point_io.h"
#include "src/tint/transform/combine_samplers.h"
#include "src/tint/transform/decompose_memory_access.h"
+#include "src/tint/transform/disable_uniformity_analysis.h"
#include "src/tint/transform/expand_compound_assignment.h"
#include "src/tint/transform/fold_trivial_single_use_lets.h"
#include "src/tint/transform/loop_to_for_loop.h"
@@ -157,6 +159,8 @@
transform::Manager manager;
transform::DataMap data;
+ manager.Add<transform::DisableUniformityAnalysis>();
+
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.count_leading_zeros = true;
@@ -687,7 +691,12 @@
}
bool GeneratorImpl::EmitCall(std::ostream& out, const ast::CallExpression* expr) {
- auto* call = builder_.Sem().Get(expr);
+ auto* sem = builder_.Sem().Get(expr);
+ if (auto* m = sem->As<sem::Materialize>()) {
+ // TODO(crbug.com/tint/1504): Just emit the constant value.
+ sem = m->Expr();
+ }
+ auto* call = sem->As<sem::Call>();
auto* target = call->Target();
if (target->Is<sem::Function>()) {
@@ -1461,8 +1470,9 @@
out << "(";
- if (!EmitExpression(out, texture))
+ if (!EmitExpression(out, texture)) {
return false;
+ }
out << ", ";
@@ -2562,6 +2572,9 @@
out << "bool";
} else if (type->Is<sem::F32>()) {
out << "float";
+ } else if (type->Is<sem::F16>()) {
+ diagnostics_.add_error(diag::System::Writer, "Type f16 is not completely implemented yet.");
+ return false;
} else if (type->Is<sem::I32>()) {
out << "int";
} else if (auto* mat = type->As<sem::Matrix>()) {
diff --git a/src/tint/writer/glsl/generator_impl_builtin_test.cc b/src/tint/writer/glsl/generator_impl_builtin_test.cc
index 1d80e6a..7942ed5 100644
--- a/src/tint/writer/glsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/glsl/generator_impl_builtin_test.cc
@@ -169,7 +169,7 @@
GeneratorImpl& gen = Build();
- auto* sem = program->Sem().Get(call);
+ auto* sem = program->Sem().Get<sem::Call>(call);
ASSERT_NE(sem, nullptr);
auto* target = sem->Target();
ASSERT_NE(target, nullptr);
diff --git a/src/tint/writer/glsl/generator_impl_test.cc b/src/tint/writer/glsl/generator_impl_test.cc
index ad11413..af2e205 100644
--- a/src/tint/writer/glsl/generator_impl_test.cc
+++ b/src/tint/writer/glsl/generator_impl_test.cc
@@ -19,6 +19,15 @@
using GlslGeneratorImplTest = TestHelper;
+TEST_F(GlslGeneratorImplTest, InvalidProgram) {
+ Diagnostics().add_error(diag::System::Writer, "make the program invalid");
+ ASSERT_FALSE(IsValid());
+ auto program = std::make_unique<Program>(std::move(*this));
+ ASSERT_FALSE(program->IsValid());
+ auto result = Generate(program.get(), Options{}, "");
+ EXPECT_EQ(result.error, "input program is not valid");
+}
+
TEST_F(GlslGeneratorImplTest, Generate) {
Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{}, ast::AttributeList{});
diff --git a/src/tint/writer/hlsl/generator.cc b/src/tint/writer/hlsl/generator.cc
index ff3ffbe..b514c2b 100644
--- a/src/tint/writer/hlsl/generator.cc
+++ b/src/tint/writer/hlsl/generator.cc
@@ -29,6 +29,10 @@
Result Generate(const Program* program, const Options& options) {
Result result;
+ if (!program->IsValid()) {
+ result.error = "input program is not valid";
+ return result;
+ }
// Sanitize the program.
auto sanitized_result = Sanitize(program, options);
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index 7ee5337..affaf5e 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -36,6 +36,7 @@
#include "src/tint/sem/depth_multisampled_texture.h"
#include "src/tint/sem/depth_texture.h"
#include "src/tint/sem/function.h"
+#include "src/tint/sem/materialize.h"
#include "src/tint/sem/member_accessor_expression.h"
#include "src/tint/sem/module.h"
#include "src/tint/sem/multisampled_texture.h"
@@ -52,6 +53,7 @@
#include "src/tint/transform/calculate_array_length.h"
#include "src/tint/transform/canonicalize_entry_point_io.h"
#include "src/tint/transform/decompose_memory_access.h"
+#include "src/tint/transform/disable_uniformity_analysis.h"
#include "src/tint/transform/expand_compound_assignment.h"
#include "src/tint/transform/fold_trivial_single_use_lets.h"
#include "src/tint/transform/localize_struct_array_assignment.h"
@@ -65,6 +67,7 @@
#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/zero_init_workgroup_memory.h"
#include "src/tint/utils/defer.h"
#include "src/tint/utils/map.h"
@@ -139,6 +142,8 @@
transform::Manager manager;
transform::DataMap data;
+ manager.Add<transform::DisableUniformityAnalysis>();
+
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
// TODO(crbug.com/tint/1449): Some of these can map to HLSL's `firstbitlow`
@@ -195,6 +200,7 @@
manager.Add<transform::ExpandCompoundAssignment>();
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::UnwindDiscardFunctions>();
+ manager.Add<transform::VectorizeScalarMatrixConstructors>();
manager.Add<transform::SimplifyPointers>();
manager.Add<transform::RemovePhonies>();
// ArrayLengthFromUniform must come after InlinePointerLets and Simplify, as
@@ -246,6 +252,10 @@
if (decl->Is<ast::Alias>()) {
continue; // Ignore aliases.
}
+ if (decl->Is<ast::Enable>()) {
+ // Currently we don't have to do anything for using a extension in HLSL.
+ continue;
+ }
// Emit a new line between declarations if the type of declaration has
// changed, or we're about to emit a function
@@ -285,11 +295,6 @@
}
return EmitFunction(func);
},
- [&](const ast::Enable*) {
- // Currently we don't have to do anything for using a extension in
- // HLSL
- return true;
- },
[&](Default) {
TINT_ICE(Writer, diagnostics_)
<< "unhandled module-scope declaration: " << decl->TypeInfo().name;
@@ -656,13 +661,8 @@
if (i != 0) {
out << ", ";
}
- if (!val.WithScalarAt(i, [&](auto&& s) -> bool {
- // Use std::equal_to to work around -Wfloat-equal warnings
- using T = std::remove_reference_t<decltype(s)>;
- auto equal_to = std::equal_to<T>{};
- bool is_zero = equal_to(s, T(0));
- return EmitValue(out, elem_ty, is_zero ? 1 : static_cast<int>(s));
- })) {
+ auto s = val.Element<AInt>(i).value;
+ if (!EmitValue(out, elem_ty, (s == 0) ? 1 : static_cast<int>(s))) {
return false;
}
}
@@ -925,7 +925,12 @@
}
bool GeneratorImpl::EmitCall(std::ostream& out, const ast::CallExpression* expr) {
- auto* call = builder_.Sem().Get(expr);
+ auto* sem = builder_.Sem().Get(expr);
+ if (auto* m = sem->As<sem::Materialize>()) {
+ // TODO(crbug.com/tint/1504): Just emit the constant value.
+ sem = m->Expr();
+ }
+ auto* call = sem->As<sem::Call>();
auto* target = call->Target();
return Switch(
target, [&](const sem::Function* func) { return EmitFunctionCall(out, call, func); },
@@ -994,23 +999,25 @@
bool GeneratorImpl::EmitBuiltinCall(std::ostream& out,
const sem::Call* call,
const sem::Builtin* builtin) {
+ const auto type = builtin->Type();
+
auto* expr = call->Declaration();
if (builtin->IsTexture()) {
return EmitTextureCall(out, call, builtin);
}
- if (builtin->Type() == sem::BuiltinType::kSelect) {
+ if (type == sem::BuiltinType::kSelect) {
return EmitSelectCall(out, expr);
}
- if (builtin->Type() == sem::BuiltinType::kModf) {
+ if (type == sem::BuiltinType::kModf) {
return EmitModfCall(out, expr, builtin);
}
- if (builtin->Type() == sem::BuiltinType::kFrexp) {
+ if (type == sem::BuiltinType::kFrexp) {
return EmitFrexpCall(out, expr, builtin);
}
- if (builtin->Type() == sem::BuiltinType::kDegrees) {
+ if (type == sem::BuiltinType::kDegrees) {
return EmitDegreesCall(out, expr, builtin);
}
- if (builtin->Type() == sem::BuiltinType::kRadians) {
+ if (type == sem::BuiltinType::kRadians) {
return EmitRadiansCall(out, expr, builtin);
}
if (builtin->IsDataPacking()) {
@@ -1025,11 +1032,30 @@
if (builtin->IsAtomic()) {
return EmitWorkgroupAtomicCall(out, expr, builtin);
}
+ if (builtin->IsDP4a()) {
+ return EmitDP4aCall(out, expr, builtin);
+ }
+
auto name = generate_builtin_name(builtin);
if (name.empty()) {
return false;
}
+ // Handle single argument builtins that only accept and return uint (not int overload). We need
+ // to explicitly cast the return value (we also cast the arg for good measure). See
+ // crbug.com/tint/1550
+ if (type == sem::BuiltinType::kCountOneBits || type == sem::BuiltinType::kReverseBits) {
+ auto* arg = call->Arguments()[0];
+ if (arg->Type()->UnwrapRef()->is_signed_scalar_or_vector()) {
+ out << "asint(" << name << "(asuint(";
+ if (!EmitExpression(out, arg->Declaration())) {
+ return false;
+ }
+ out << ")))";
+ return true;
+ }
+ }
+
out << name << "(";
bool first = true;
@@ -1045,6 +1071,7 @@
}
out << ")";
+
return true;
}
@@ -1075,6 +1102,55 @@
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;
+ }
+ }
+
bool brackets = type->IsAnyOf<sem::Array, sem::Struct>();
// For single-value vector initializers, swizzle the scalar to the right
@@ -1135,7 +1211,7 @@
if (auto val = offset_arg->ConstantValue()) {
TINT_ASSERT(Writer, val.Type()->Is<sem::U32>());
- scalar_offset_value = val.Elements()[0].u32;
+ scalar_offset_value = static_cast<uint32_t>(val.Element<AInt>(0).value);
scalar_offset_value /= 4; // bytes -> scalar index
scalar_offset_constant = true;
}
@@ -2031,6 +2107,34 @@
});
}
+bool GeneratorImpl::EmitDP4aCall(std::ostream& out,
+ const ast::CallExpression* expr,
+ const sem::Builtin* builtin) {
+ // TODO(crbug.com/tint/1497): support the polyfill version of DP4a functions.
+ return CallBuiltinHelper(
+ out, expr, builtin, [&](TextBuffer* b, const std::vector<std::string>& params) {
+ std::string functionName;
+ switch (builtin->Type()) {
+ case sem::BuiltinType::kDot4I8Packed:
+ line(b) << "int accumulator = 0;";
+ functionName = "dot4add_i8packed";
+ break;
+ case sem::BuiltinType::kDot4U8Packed:
+ line(b) << "uint accumulator = 0u;";
+ functionName = "dot4add_u8packed";
+ break;
+ default:
+ diagnostics_.add_error(diag::System::Writer,
+ "Internal error: unhandled DP4a builtin");
+ return false;
+ }
+ line(b) << "return " << functionName << "(" << params[0] << ", " << params[1]
+ << ", accumulator);";
+
+ return true;
+ });
+}
+
bool GeneratorImpl::EmitBarrierCall(std::ostream& out, const sem::Builtin* builtin) {
// TODO(crbug.com/tint/661): Combine sequential barriers to a single
// instruction.
@@ -2245,8 +2349,9 @@
break;
}
- if (!EmitExpression(out, texture))
+ if (!EmitExpression(out, texture)) {
return false;
+ }
// If pack_level_in_coords is true, then the mip level will be appended as the
// last value of the coordinates argument. If the WGSL builtin overload does
@@ -2287,7 +2392,7 @@
case sem::BuiltinType::kTextureGather:
out << ".Gather";
if (builtin->Parameters()[0]->Usage() == sem::ParameterUsage::kComponent) {
- switch (call->Arguments()[0]->ConstantValue().Elements()[0].i32) {
+ switch (call->Arguments()[0]->ConstantValue().Element<AInt>(0).value) {
case 0:
out << "Red";
break;
@@ -2318,8 +2423,9 @@
}
if (auto* sampler = arg(Usage::kSampler)) {
- if (!EmitExpression(out, sampler))
+ if (!EmitExpression(out, sampler)) {
return false;
+ }
out << ", ";
}
@@ -2459,7 +2565,7 @@
case sem::BuiltinType::kTranspose:
case sem::BuiltinType::kTrunc:
return builtin->str();
- case sem::BuiltinType::kCountOneBits:
+ case sem::BuiltinType::kCountOneBits: // uint
return "countbits";
case sem::BuiltinType::kDpdx:
return "ddx";
@@ -2487,7 +2593,7 @@
return "rsqrt";
case sem::BuiltinType::kMix:
return "lerp";
- case sem::BuiltinType::kReverseBits:
+ case sem::BuiltinType::kReverseBits: // uint
return "reversebits";
case sem::BuiltinType::kSmoothstep:
case sem::BuiltinType::kSmoothStep:
@@ -3482,6 +3588,11 @@
out << "float";
return true;
},
+ [&](const sem::F16*) {
+ diagnostics_.add_error(diag::System::Writer,
+ "Type f16 is not completely implemented yet.");
+ return false;
+ },
[&](const sem::I32*) {
out << "int";
return true;
diff --git a/src/tint/writer/hlsl/generator_impl.h b/src/tint/writer/hlsl/generator_impl.h
index e329638..86bbd7d 100644
--- a/src/tint/writer/hlsl/generator_impl.h
+++ b/src/tint/writer/hlsl/generator_impl.h
@@ -242,7 +242,7 @@
/// Handles generating a call to data packing builtin
/// @param out the output of the expression stream
/// @param expr the call expression
- /// @param builtin the semantic information for the texture builtin
+ /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitDataPackingCall(std::ostream& out,
const ast::CallExpression* expr,
@@ -250,11 +250,19 @@
/// Handles generating a call to data unpacking builtin
/// @param out the output of the expression stream
/// @param expr the call expression
- /// @param builtin the semantic information for the texture builtin
+ /// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitDataUnpackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Builtin* builtin);
+ /// Handles generating a call to DP4a builtins (dot4I8Packed and dot4U8Packed)
+ /// @param out the output of the expression stream
+ /// @param expr the call expression
+ /// @param builtin the semantic information for the builtin
+ /// @returns true if the call expression is emitted
+ bool EmitDP4aCall(std::ostream& out,
+ const ast::CallExpression* expr,
+ const sem::Builtin* builtin);
/// Handles a case statement
/// @param s the switch statement
/// @param case_idx the index of the switch case in the switch statement
@@ -504,6 +512,7 @@
TextBuffer helpers_; // Helper functions emitted at the top of the output
std::function<bool()> emit_continuing_;
std::unordered_map<DMAIntrinsic, std::string, DMAIntrinsic::Hasher> dma_intrinsics_;
+ std::unordered_map<const sem::Matrix*, std::string> matrix_scalar_ctors_;
std::unordered_map<const sem::Builtin*, std::string> builtins_;
std::unordered_map<const sem::Struct*, std::string> structure_builders_;
std::unordered_map<const sem::Vector*, std::string> dynamic_vector_write_;
diff --git a/src/tint/writer/hlsl/generator_impl_builtin_test.cc b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
index e4e6ba9..40f550b 100644
--- a/src/tint/writer/hlsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
@@ -168,7 +168,7 @@
GeneratorImpl& gen = Build();
- auto* sem = program->Sem().Get(call);
+ auto* sem = program->Sem().Get<sem::Call>(call);
ASSERT_NE(sem, nullptr);
auto* target = sem->Target();
ASSERT_NE(target, nullptr);
@@ -726,5 +726,91 @@
)");
}
+TEST_F(HlslGeneratorImplTest_Builtin, Dot4I8Packed) {
+ Enable(ast::Extension::kChromiumExperimentalDP4a);
+
+ auto* val1 = Var("val1", ty.u32());
+ auto* val2 = Var("val2", ty.u32());
+ auto* call = Call("dot4I8Packed", val1, val2);
+ WrapInFunction(val1, val2, call);
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(int tint_dot4I8Packed(uint param_0, uint param_1) {
+ int accumulator = 0;
+ return dot4add_i8packed(param_0, param_1, accumulator);
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+ uint val1 = 0u;
+ uint val2 = 0u;
+ const int tint_symbol = tint_dot4I8Packed(val1, val2);
+ return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, Dot4U8Packed) {
+ Enable(ast::Extension::kChromiumExperimentalDP4a);
+
+ auto* val1 = Var("val1", ty.u32());
+ auto* val2 = Var("val2", ty.u32());
+ auto* call = Call("dot4U8Packed", val1, val2);
+ WrapInFunction(val1, val2, call);
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"(uint tint_dot4U8Packed(uint param_0, uint param_1) {
+ uint accumulator = 0u;
+ return dot4add_u8packed(param_0, param_1, accumulator);
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+ uint val1 = 0u;
+ uint val2 = 0u;
+ const uint tint_symbol = tint_dot4U8Packed(val1, val2);
+ return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, CountOneBits) {
+ auto* val = Var("val1", ty.i32());
+ auto* call = Call("countOneBits", val);
+ WrapInFunction(val, call);
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"([numthreads(1, 1, 1)]
+void test_function() {
+ int val1 = 0;
+ const int tint_symbol = asint(countbits(asuint(val1)));
+ return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, ReverseBits) {
+ auto* val = Var("val1", ty.i32());
+ auto* call = Call("reverseBits", val);
+ WrapInFunction(val, call);
+
+ GeneratorImpl& gen = SanitizeAndBuild();
+
+ ASSERT_TRUE(gen.Generate()) << gen.error();
+ EXPECT_EQ(gen.result(), R"([numthreads(1, 1, 1)]
+void test_function() {
+ int val1 = 0;
+ const int tint_symbol = asint(reversebits(asuint(val1)));
+ return;
+}
+)");
+}
+
} // namespace
} // namespace tint::writer::hlsl
diff --git a/src/tint/writer/hlsl/generator_impl_test.cc b/src/tint/writer/hlsl/generator_impl_test.cc
index 460b202..a1e0edb 100644
--- a/src/tint/writer/hlsl/generator_impl_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_test.cc
@@ -19,6 +19,15 @@
using HlslGeneratorImplTest = TestHelper;
+TEST_F(HlslGeneratorImplTest, InvalidProgram) {
+ Diagnostics().add_error(diag::System::Writer, "make the program invalid");
+ ASSERT_FALSE(IsValid());
+ auto program = std::make_unique<Program>(std::move(*this));
+ ASSERT_FALSE(program->IsValid());
+ auto result = Generate(program.get(), Options{});
+ EXPECT_EQ(result.error, "input program is not valid");
+}
+
TEST_F(HlslGeneratorImplTest, Generate) {
Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{}, ast::AttributeList{});
diff --git a/src/tint/writer/msl/generator.cc b/src/tint/writer/msl/generator.cc
index 6d09a86..5cd9ac8 100644
--- a/src/tint/writer/msl/generator.cc
+++ b/src/tint/writer/msl/generator.cc
@@ -31,6 +31,10 @@
Result Generate(const Program* program, const Options& options) {
Result result;
+ if (!program->IsValid()) {
+ result.error = "input program is not valid";
+ return result;
+ }
// Sanitize the program.
auto sanitized_result = Sanitize(program, options);
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc
index 8f5800c..be94e2c 100644
--- a/src/tint/writer/msl/generator_impl.cc
+++ b/src/tint/writer/msl/generator_impl.cc
@@ -41,6 +41,7 @@
#include "src/tint/sem/f32.h"
#include "src/tint/sem/function.h"
#include "src/tint/sem/i32.h"
+#include "src/tint/sem/materialize.h"
#include "src/tint/sem/matrix.h"
#include "src/tint/sem/member_accessor_expression.h"
#include "src/tint/sem/module.h"
@@ -59,6 +60,7 @@
#include "src/tint/transform/array_length_from_uniform.h"
#include "src/tint/transform/builtin_polyfill.h"
#include "src/tint/transform/canonicalize_entry_point_io.h"
+#include "src/tint/transform/disable_uniformity_analysis.h"
#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"
@@ -121,6 +123,8 @@
transform::Manager manager;
transform::DataMap data;
+ manager.Add<transform::DisableUniformityAnalysis>();
+
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.extract_bits = transform::BuiltinPolyfill::Level::kClampParameters;
@@ -510,6 +514,22 @@
return true;
}
+ // Handle '&' and '|' of booleans.
+ if ((expr->IsAnd() || expr->IsOr()) && lhs_type->Is<sem::Bool>()) {
+ out << "bool";
+ ScopedParen sp(out);
+ if (!EmitExpression(out, expr->lhs)) {
+ return false;
+ }
+ if (!emit_op()) {
+ return false;
+ }
+ if (!EmitExpression(out, expr->rhs)) {
+ return false;
+ }
+ return true;
+ }
+
// Emit as usual
ScopedParen sp(out);
if (!EmitExpression(out, expr->lhs)) {
@@ -531,7 +551,12 @@
}
bool GeneratorImpl::EmitCall(std::ostream& out, const ast::CallExpression* expr) {
- auto* call = program_->Sem().Get(expr);
+ auto* sem = program_->Sem().Get(expr);
+ if (auto* m = sem->As<sem::Materialize>()) {
+ // TODO(crbug.com/tint/1504): Just emit the constant value.
+ sem = m->Expr();
+ }
+ auto* call = sem->As<sem::Call>();
auto* target = call->Target();
return Switch(
target, [&](const sem::Function* func) { return EmitFunctionCall(out, call, func); },
@@ -1024,8 +1049,9 @@
}
}
- if (!EmitExpression(out, e->Declaration()))
+ if (!EmitExpression(out, e->Declaration())) {
return false;
+ }
if (casted) {
out << ")";
@@ -1117,8 +1143,8 @@
break; // Other texture dimensions don't have an offset
}
}
- auto c = component->ConstantValue().Elements()[0].i32;
- switch (c) {
+ auto c = component->ConstantValue().Element<AInt>(0);
+ switch (c.value) {
case 0:
out << "component::x";
break;
@@ -1464,6 +1490,12 @@
out << "false";
return true;
},
+ [&](const sem::F16*) {
+ // Placeholder for emitting f16 zero value
+ diagnostics_.add_error(diag::System::Writer,
+ "Type f16 is not completely implemented yet");
+ return false;
+ },
[&](const sem::F32*) {
out << "0.0f";
return true;
@@ -2236,6 +2268,11 @@
out << "bool";
return true;
},
+ [&](const sem::F16*) {
+ diagnostics_.add_error(diag::System::Writer,
+ "Type f16 is not completely implemented yet");
+ return false;
+ },
[&](const sem::F32*) {
out << "float";
return true;
diff --git a/src/tint/writer/msl/generator_impl_binary_test.cc b/src/tint/writer/msl/generator_impl_binary_test.cc
index 5262b97..02daae2 100644
--- a/src/tint/writer/msl/generator_impl_binary_test.cc
+++ b/src/tint/writer/msl/generator_impl_binary_test.cc
@@ -171,5 +171,31 @@
EXPECT_EQ(out.str(), "fmod(left, right)");
}
+TEST_F(MslBinaryTest, BoolAnd) {
+ auto* left = Var("left", nullptr, Expr(true));
+ auto* right = Var("right", nullptr, Expr(false));
+ auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kAnd, Expr(left), Expr(right));
+ WrapInFunction(left, right, expr);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
+ EXPECT_EQ(out.str(), "bool(left & right)");
+}
+
+TEST_F(MslBinaryTest, BoolOr) {
+ auto* left = Var("left", nullptr, Expr(true));
+ auto* right = Var("right", nullptr, Expr(false));
+ auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kOr, Expr(left), Expr(right));
+ WrapInFunction(left, right, expr);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
+ EXPECT_EQ(out.str(), "bool(left | right)");
+}
+
} // namespace
} // namespace tint::writer::msl
diff --git a/src/tint/writer/msl/generator_impl_builtin_test.cc b/src/tint/writer/msl/generator_impl_builtin_test.cc
index 752fc73..0c1f2a4 100644
--- a/src/tint/writer/msl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/msl/generator_impl_builtin_test.cc
@@ -189,7 +189,7 @@
GeneratorImpl& gen = Build();
- auto* sem = program->Sem().Get(call);
+ auto* sem = program->Sem().Get<sem::Call>(call);
ASSERT_NE(sem, nullptr);
auto* target = sem->Target();
ASSERT_NE(target, nullptr);
diff --git a/src/tint/writer/msl/generator_impl_import_test.cc b/src/tint/writer/msl/generator_impl_import_test.cc
index 8a6d2d0..de9353e 100644
--- a/src/tint/writer/msl/generator_impl_import_test.cc
+++ b/src/tint/writer/msl/generator_impl_import_test.cc
@@ -40,7 +40,7 @@
GeneratorImpl& gen = Build();
- auto* sem = program->Sem().Get(call);
+ auto* sem = program->Sem().Get<sem::Call>(call);
ASSERT_NE(sem, nullptr);
auto* target = sem->Target();
ASSERT_NE(target, nullptr);
diff --git a/src/tint/writer/msl/generator_impl_test.cc b/src/tint/writer/msl/generator_impl_test.cc
index b5af8e4..dd90715 100644
--- a/src/tint/writer/msl/generator_impl_test.cc
+++ b/src/tint/writer/msl/generator_impl_test.cc
@@ -22,6 +22,15 @@
using MslGeneratorImplTest = TestHelper;
+TEST_F(MslGeneratorImplTest, InvalidProgram) {
+ Diagnostics().add_error(diag::System::Writer, "make the program invalid");
+ ASSERT_FALSE(IsValid());
+ auto program = std::make_unique<Program>(std::move(*this));
+ ASSERT_FALSE(program->IsValid());
+ auto result = Generate(program.get(), Options{});
+ EXPECT_EQ(result.error, "input program is not valid");
+}
+
TEST_F(MslGeneratorImplTest, Generate) {
Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{},
ast::AttributeList{
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index 7d232c0..5f8072b 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -30,6 +30,7 @@
#include "src/tint/sem/depth_multisampled_texture.h"
#include "src/tint/sem/depth_texture.h"
#include "src/tint/sem/function.h"
+#include "src/tint/sem/materialize.h"
#include "src/tint/sem/member_accessor_expression.h"
#include "src/tint/sem/module.h"
#include "src/tint/sem/multisampled_texture.h"
@@ -55,8 +56,9 @@
uint32_t size_of(const InstructionList& instructions) {
uint32_t size = 0;
- for (const auto& inst : instructions)
+ for (const auto& inst : instructions) {
size += inst.word_length();
+ }
return size;
}
@@ -256,7 +258,7 @@
push_memory_model(spv::Op::OpMemoryModel,
{U32Operand(SpvAddressingModelLogical), U32Operand(SpvMemoryModelGLSL450)});
- for (auto ext : builder_.AST().Extensions()) {
+ for (auto ext : builder_.Sem().Module()->Extensions()) {
GenerateExtension(ext);
}
@@ -366,7 +368,7 @@
}
}
-bool Builder::GenerateExtension(ast::Enable::ExtensionKind) {
+bool Builder::GenerateExtension(ast::Extension) {
/*
For each supported extension, push corresponding capability into the builder.
For example:
@@ -1272,7 +1274,13 @@
return ast::TraverseAction::Descend;
}
if (auto* ce = e->As<ast::CallExpression>()) {
- auto* call = builder_.Sem().Get(ce);
+ auto* sem = builder_.Sem().Get(ce);
+ if (sem->Is<sem::Materialize>()) {
+ // Materialize can only occur on compile time expressions, so this sub-tree must be
+ // constant.
+ return ast::TraverseAction::Skip;
+ }
+ auto* call = sem->As<sem::Call>();
if (call->Target()->Is<sem::TypeConstructor>()) {
return ast::TraverseAction::Descend;
}
@@ -1628,6 +1636,8 @@
constant.kind = ScalarConstant::Kind::kF32;
constant.value.f32 = static_cast<float>(f->value);
return;
+ case ast::FloatLiteralExpression::Suffix::kH:
+ error_ = "Type f16 is not completely implemented yet";
}
},
[&](Default) { error_ = "unknown literal type"; });
@@ -2151,7 +2161,12 @@
}
uint32_t Builder::GenerateCallExpression(const ast::CallExpression* expr) {
- auto* call = builder_.Sem().Get(expr);
+ auto* sem = builder_.Sem().Get(expr);
+ if (auto* m = sem->As<sem::Materialize>()) {
+ // TODO(crbug.com/tint/1504): Just emit the constant value.
+ sem = m->Expr();
+ }
+ auto* call = sem->As<sem::Call>();
auto* target = call->Target();
return Switch(
target, [&](const sem::Function* func) { return GenerateFunctionCall(call, func); },
@@ -3672,6 +3687,11 @@
push_type(spv::Op::OpTypeFloat, {result, Operand(32u)});
return true;
},
+ [&](const sem::F16*) {
+ // Should be `push_type(spv::Op::OpTypeFloat, {result, Operand(16u)});`
+ error_ = "Type f16 is not completely implemented yet.";
+ return false;
+ },
[&](const sem::I32*) {
push_type(spv::Op::OpTypeInt, {result, Operand(32u), Operand(1u)});
return true;
diff --git a/src/tint/writer/spirv/builder.h b/src/tint/writer/spirv/builder.h
index 34cfd76..1745ed5 100644
--- a/src/tint/writer/spirv/builder.h
+++ b/src/tint/writer/spirv/builder.h
@@ -224,11 +224,11 @@
ast::InterpolationType type,
ast::InterpolationSampling sampling);
- /// Generates a extension for the given extension kind. Emits an error and
- /// returns false if the extension kind is not supported.
- /// @param kind ExtensionKind of the extension to generate
+ /// Generates the enabling of an extension. Emits an error and returns false if the extension is
+ /// not supported.
+ /// @param ext the extension to generate
/// @returns true on success.
- bool GenerateExtension(ast::Enable::ExtensionKind kind);
+ bool GenerateExtension(ast::Extension ext);
/// Generates a label for the given id. Emits an error and returns false if
/// we're currently outside a function.
/// @param id the id to use for the label
diff --git a/src/tint/writer/spirv/builder_test.cc b/src/tint/writer/spirv/builder_test.cc
index f2475c0..3548f9a 100644
--- a/src/tint/writer/spirv/builder_test.cc
+++ b/src/tint/writer/spirv/builder_test.cc
@@ -20,6 +20,15 @@
using BuilderTest = TestHelper;
+TEST_F(BuilderTest, InvalidProgram) {
+ Diagnostics().add_error(diag::System::Writer, "make the program invalid");
+ ASSERT_FALSE(IsValid());
+ auto program = std::make_unique<Program>(std::move(*this));
+ ASSERT_FALSE(program->IsValid());
+ auto result = Generate(program.get(), Options{});
+ EXPECT_EQ(result.error, "input program is not valid");
+}
+
TEST_F(BuilderTest, TracksIdBounds) {
spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/generator.cc b/src/tint/writer/spirv/generator.cc
index fa67827..93ac6e1 100644
--- a/src/tint/writer/spirv/generator.cc
+++ b/src/tint/writer/spirv/generator.cc
@@ -26,6 +26,10 @@
Result Generate(const Program* program, const Options& options) {
Result result;
+ if (!program->IsValid()) {
+ result.error = "input program is not valid";
+ return result;
+ }
// Sanitize the program.
auto sanitized_result = Sanitize(program, options);
diff --git a/src/tint/writer/spirv/generator_impl.cc b/src/tint/writer/spirv/generator_impl.cc
index e466a24..21216bf 100644
--- a/src/tint/writer/spirv/generator_impl.cc
+++ b/src/tint/writer/spirv/generator_impl.cc
@@ -21,6 +21,7 @@
#include "src/tint/transform/add_spirv_block_attribute.h"
#include "src/tint/transform/builtin_polyfill.h"
#include "src/tint/transform/canonicalize_entry_point_io.h"
+#include "src/tint/transform/disable_uniformity_analysis.h"
#include "src/tint/transform/expand_compound_assignment.h"
#include "src/tint/transform/fold_constants.h"
#include "src/tint/transform/for_loop_to_loop.h"
@@ -41,6 +42,8 @@
transform::Manager manager;
transform::DataMap data;
+ manager.Add<transform::DisableUniformityAnalysis>();
+
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.count_leading_zeros = true;
diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc
index 3ef6269..677421d 100644
--- a/src/tint/writer/wgsl/generator_impl.cc
+++ b/src/tint/writer/wgsl/generator_impl.cc
@@ -62,12 +62,12 @@
bool GeneratorImpl::Generate() {
// Generate enable directives before any other global declarations.
- for (auto ext : program_->AST().Extensions()) {
- if (!EmitEnableDirective(ext)) {
+ for (auto enable : program_->AST().Enables()) {
+ if (!EmitEnable(enable)) {
return false;
}
}
- if (!program_->AST().Extensions().empty()) {
+ if (!program_->AST().Enables().empty()) {
line();
}
// Generate global declarations in the order they appear in the module.
@@ -94,13 +94,9 @@
return true;
}
-bool GeneratorImpl::EmitEnableDirective(const ast::Enable::ExtensionKind ext) {
+bool GeneratorImpl::EmitEnable(const ast::Enable* enable) {
auto out = line();
- auto extension = ast::Enable::KindToName(ext);
- if (extension == "") {
- return false;
- }
- out << "enable " << extension << ";";
+ out << "enable " << enable->extension << ";";
return true;
}
@@ -405,6 +401,11 @@
out << "f32";
return true;
},
+ [&](const ast::F16*) {
+ diagnostics_.add_error(diag::System::Writer,
+ "Type f16 is not completely implemented yet.");
+ return false;
+ },
[&](const ast::I32*) {
out << "i32";
return true;
diff --git a/src/tint/writer/wgsl/generator_impl.h b/src/tint/writer/wgsl/generator_impl.h
index 8473b4f..a17e2da 100644
--- a/src/tint/writer/wgsl/generator_impl.h
+++ b/src/tint/writer/wgsl/generator_impl.h
@@ -53,9 +53,9 @@
bool Generate();
/// Handles generating a enable directive
- /// @param ext the extension kind in the enable directive to generate
+ /// @param enable the enable node
/// @returns true if the enable directive was emitted
- bool EmitEnableDirective(const ast::Enable::ExtensionKind ext);
+ bool EmitEnable(const ast::Enable* enable);
/// Handles generating a declared type
/// @param ty the declared type to generate
/// @returns true if the declared type was emitted
diff --git a/src/tint/writer/wgsl/generator_impl_enable_test.cc b/src/tint/writer/wgsl/generator_impl_enable_test.cc
index f9de371..503a9a0 100644
--- a/src/tint/writer/wgsl/generator_impl_enable_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_enable_test.cc
@@ -20,10 +20,12 @@
using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_Enable) {
+ auto* enable = Enable(ast::Extension::kF16);
+
GeneratorImpl& gen = Build();
- ASSERT_TRUE(gen.EmitEnableDirective(ast::Enable::ExtensionKind::kInternalExtensionForTesting));
- EXPECT_EQ(gen.result(), R"(enable InternalExtensionForTesting;
+ ASSERT_TRUE(gen.EmitEnable(enable));
+ EXPECT_EQ(gen.result(), R"(enable f16;
)");
}
diff --git a/test/tint/BUILD.gn b/test/tint/BUILD.gn
index bed8729..2ef1202 100644
--- a/test/tint/BUILD.gn
+++ b/test/tint/BUILD.gn
@@ -164,7 +164,9 @@
"../../src/tint/ast/depth_texture_test.cc",
"../../src/tint/ast/discard_statement_test.cc",
"../../src/tint/ast/enable_test.cc",
+ "../../src/tint/ast/extension_test.cc",
"../../src/tint/ast/external_texture_test.cc",
+ "../../src/tint/ast/f16_test.cc",
"../../src/tint/ast/f32_test.cc",
"../../src/tint/ast/fallthrough_statement_test.cc",
"../../src/tint/ast/float_literal_expression_test.cc",
@@ -272,6 +274,7 @@
"../../src/tint/resolver/struct_storage_class_use_test.cc",
"../../src/tint/resolver/type_constructor_validation_test.cc",
"../../src/tint/resolver/type_validation_test.cc",
+ "../../src/tint/resolver/uniformity_test.cc",
"../../src/tint/resolver/validation_test.cc",
"../../src/tint/resolver/validator_is_storeable_test.cc",
"../../src/tint/resolver/var_let_test.cc",
@@ -287,7 +290,9 @@
"../../src/tint/sem/builtin_test.cc",
"../../src/tint/sem/depth_multisampled_texture_test.cc",
"../../src/tint/sem/depth_texture_test.cc",
+ "../../src/tint/sem/expression_test.cc",
"../../src/tint/sem/external_texture_test.cc",
+ "../../src/tint/sem/f16_test.cc",
"../../src/tint/sem/f32_test.cc",
"../../src/tint/sem/i32_test.cc",
"../../src/tint/sem/matrix_test.cc",
@@ -300,6 +305,7 @@
"../../src/tint/sem/sem_struct_test.cc",
"../../src/tint/sem/storage_texture_test.cc",
"../../src/tint/sem/texture_test.cc",
+ "../../src/tint/sem/type_test.cc",
"../../src/tint/sem/type_manager_test.cc",
"../../src/tint/sem/u32_test.cc",
"../../src/tint/sem/vector_test.cc",
@@ -323,6 +329,7 @@
"../../src/tint/transform/decompose_memory_access_test.cc",
"../../src/tint/transform/decompose_strided_array_test.cc",
"../../src/tint/transform/decompose_strided_matrix_test.cc",
+ "../../src/tint/transform/disable_uniformity_analysis_test.cc",
"../../src/tint/transform/expand_compound_assignment_test.cc",
"../../src/tint/transform/first_index_offset_test.cc",
"../../src/tint/transform/fold_constants_test.cc",