Rename 'intrinsic' to 'builtin'

This matches the term used in the WGSL spec.

Change-Id: I4603332b828450c126ef806f1064ed54f372013f
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/78787
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2022-02-02 23:07:11 +00:00
parent a996ffbd1f
commit b85e692aa7
4600 changed files with 6765 additions and 6819 deletions

View File

@ -117,7 +117,7 @@ type nodes.
Semantic information is held by `sem::Node`s which describe the program at
a higher / more abstract level than the AST. This includes information such as
the resolved type of each expression, the resolved overload of an intrinsic
the resolved type of each expression, the resolved overload of a builtin
function call, and the module scoped variables used by each function.
Semantic information is generated by the `Resolver` when the `Program`

View File

@ -337,6 +337,9 @@ libtint_source_set("libtint_core_all_src") {
"ast/workgroup_attribute.cc",
"ast/workgroup_attribute.h",
"block_allocator.h",
"builtin_table.cc",
"builtin_table.h",
"builtin_table.inl",
"castable.cc",
"castable.h",
"clone_context.cc",
@ -359,9 +362,6 @@ libtint_source_set("libtint_core_all_src") {
"inspector/resource_binding.h",
"inspector/scalar.cc",
"inspector/scalar.h",
"intrinsic_table.cc",
"intrinsic_table.h",
"intrinsic_table.inl",
"program.cc",
"program.h",
"program_builder.cc",
@ -382,6 +382,8 @@ libtint_source_set("libtint_core_all_src") {
"sem/behavior.h",
"sem/binding_point.h",
"sem/bool_type.h",
"sem/builtin.h",
"sem/builtin_type.h",
"sem/call.h",
"sem/call_target.h",
"sem/constant.h",
@ -394,8 +396,6 @@ libtint_source_set("libtint_core_all_src") {
"sem/i32_type.h",
"sem/if_statement.h",
"sem/info.h",
"sem/intrinsic.h",
"sem/intrinsic_type.h",
"sem/loop_statement.h",
"sem/matrix_type.h",
"sem/multisampled_texture_type.h",
@ -536,6 +536,10 @@ libtint_source_set("libtint_sem_src") {
"sem/block_statement.cc",
"sem/bool_type.cc",
"sem/bool_type.h",
"sem/builtin.cc",
"sem/builtin.h",
"sem/builtin_type.cc",
"sem/builtin_type.h",
"sem/call.cc",
"sem/call.h",
"sem/call_target.cc",
@ -561,10 +565,6 @@ libtint_source_set("libtint_sem_src") {
"sem/if_statement.h",
"sem/info.cc",
"sem/info.h",
"sem/intrinsic.cc",
"sem/intrinsic.h",
"sem/intrinsic_type.cc",
"sem/intrinsic_type.h",
"sem/loop_statement.cc",
"sem/loop_statement.h",
"sem/matrix_type.cc",

View File

@ -219,6 +219,9 @@ set(TINT_LIB_SRCS
ast/workgroup_attribute.cc
ast/workgroup_attribute.h
block_allocator.h
builtin_table.cc
builtin_table.h
builtin_table.inl
castable.cc
castable.h
clone_context.cc
@ -233,9 +236,6 @@ set(TINT_LIB_SRCS
inspector/resource_binding.h
inspector/scalar.cc
inspector/scalar.h
intrinsic_table.cc
intrinsic_table.h
intrinsic_table.inl
program_builder.cc
program_builder.h
program_id.cc
@ -260,6 +260,10 @@ set(TINT_LIB_SRCS
sem/binding_point.h
sem/block_statement.cc
sem/block_statement.h
sem/builtin_type.cc
sem/builtin_type.h
sem/builtin.cc
sem/builtin.h
sem/call_target.cc
sem/call_target.h
sem/call.cc
@ -273,10 +277,6 @@ set(TINT_LIB_SRCS
sem/function.cc
sem/info.cc
sem/info.h
sem/intrinsic_type.cc
sem/intrinsic_type.h
sem/intrinsic.cc
sem/intrinsic.h
sem/member_accessor_expression.cc
sem/parameter_usage.cc
sem/parameter_usage.h
@ -624,6 +624,8 @@ if(TINT_BUILD_TESTS)
ast/bool_test.cc
ast/break_statement_test.cc
ast/builtin_attribute_test.cc
ast/builtin_texture_helper_test.cc
ast/builtin_texture_helper_test.h
ast/call_expression_test.cc
ast/call_statement_test.cc
ast/case_statement_test.cc
@ -645,8 +647,6 @@ if(TINT_BUILD_TESTS)
ast/index_accessor_expression_test.cc
ast/int_literal_expression_test.cc
ast/interpolate_attribute_test.cc
ast/intrinsic_texture_helper_test.cc
ast/intrinsic_texture_helper_test.h
ast/invariant_attribute_test.cc
ast/location_attribute_test.cc
ast/loop_statement_test.cc
@ -682,6 +682,7 @@ if(TINT_BUILD_TESTS)
ast/vector_test.cc
ast/workgroup_attribute_test.cc
block_allocator_test.cc
builtin_table_test.cc
castable_test.cc
clone_context_test.cc
debug_test.cc
@ -689,7 +690,6 @@ if(TINT_BUILD_TESTS)
diagnostic/diagnostic_test.cc
diagnostic/formatter_test.cc
diagnostic/printer_test.cc
intrinsic_table_test.cc
program_test.cc
resolver/array_accessor_test.cc
resolver/assignment_validation_test.cc
@ -697,6 +697,8 @@ if(TINT_BUILD_TESTS)
resolver/atomics_validation_test.cc
resolver/bitcast_validation_test.cc
resolver/builtins_validation_test.cc
resolver/builtin_test.cc
resolver/builtin_validation_test.cc
resolver/call_test.cc
resolver/call_validation_test.cc
resolver/compound_statement_test.cc
@ -707,8 +709,6 @@ if(TINT_BUILD_TESTS)
resolver/function_validation_test.cc
resolver/host_shareable_validation_test.cc
resolver/inferred_type_test.cc
resolver/intrinsic_test.cc
resolver/intrinsic_validation_test.cc
resolver/is_host_shareable_test.cc
resolver/is_storeable_test.cc
resolver/pipeline_overridable_constant_test.cc
@ -732,12 +732,12 @@ if(TINT_BUILD_TESTS)
scope_stack_test.cc
sem/atomic_type_test.cc
sem/bool_type_test.cc
sem/builtin_test.cc
sem/depth_multisampled_texture_type_test.cc
sem/depth_texture_type_test.cc
sem/external_texture_type_test.cc
sem/f32_type_test.cc
sem/i32_type_test.cc
sem/intrinsic_test.cc
sem/matrix_type_test.cc
sem/multisampled_texture_type_test.cc
sem/pointer_type_test.cc
@ -911,6 +911,8 @@ if(TINT_BUILD_TESTS)
writer/spirv/builder_binary_expression_test.cc
writer/spirv/builder_bitcast_expression_test.cc
writer/spirv/builder_block_test.cc
writer/spirv/builder_builtin_test.cc
writer/spirv/builder_builtin_texture_test.cc
writer/spirv/builder_call_test.cc
writer/spirv/builder_constructor_expression_test.cc
writer/spirv/builder_discard_test.cc
@ -922,8 +924,6 @@ if(TINT_BUILD_TESTS)
writer/spirv/builder_global_variable_test.cc
writer/spirv/builder_ident_expression_test.cc
writer/spirv/builder_if_test.cc
writer/spirv/builder_intrinsic_test.cc
writer/spirv/builder_intrinsic_texture_test.cc
writer/spirv/builder_literal_test.cc
writer/spirv/builder_loop_test.cc
writer/spirv/builder_return_test.cc
@ -1020,6 +1020,8 @@ if(TINT_BUILD_TESTS)
writer/msl/generator_impl_bitcast_test.cc
writer/msl/generator_impl_block_test.cc
writer/msl/generator_impl_break_test.cc
writer/msl/generator_impl_builtin_test.cc
writer/msl/generator_impl_builtin_texture_test.cc
writer/msl/generator_impl_call_test.cc
writer/msl/generator_impl_case_test.cc
writer/msl/generator_impl_cast_test.cc
@ -1030,8 +1032,6 @@ if(TINT_BUILD_TESTS)
writer/msl/generator_impl_identifier_test.cc
writer/msl/generator_impl_if_test.cc
writer/msl/generator_impl_import_test.cc
writer/msl/generator_impl_intrinsic_test.cc
writer/msl/generator_impl_intrinsic_texture_test.cc
writer/msl/generator_impl_loop_test.cc
writer/msl/generator_impl_member_accessor_test.cc
writer/msl/generator_impl_module_constant_test.cc
@ -1054,6 +1054,8 @@ if(TINT_BUILD_TESTS)
writer/glsl/generator_impl_bitcast_test.cc
writer/glsl/generator_impl_block_test.cc
writer/glsl/generator_impl_break_test.cc
writer/glsl/generator_impl_builtin_test.cc
writer/glsl/generator_impl_builtin_texture_test.cc
writer/glsl/generator_impl_call_test.cc
writer/glsl/generator_impl_case_test.cc
writer/glsl/generator_impl_cast_test.cc
@ -1063,8 +1065,6 @@ if(TINT_BUILD_TESTS)
writer/glsl/generator_impl_function_test.cc
writer/glsl/generator_impl_identifier_test.cc
writer/glsl/generator_impl_if_test.cc
writer/glsl/generator_impl_intrinsic_test.cc
writer/glsl/generator_impl_intrinsic_texture_test.cc
writer/glsl/generator_impl_import_test.cc
writer/glsl/generator_impl_loop_test.cc
writer/glsl/generator_impl_member_accessor_test.cc
@ -1089,6 +1089,8 @@ if(TINT_BUILD_TESTS)
writer/hlsl/generator_impl_bitcast_test.cc
writer/hlsl/generator_impl_block_test.cc
writer/hlsl/generator_impl_break_test.cc
writer/hlsl/generator_impl_builtin_test.cc
writer/hlsl/generator_impl_builtin_texture_test.cc
writer/hlsl/generator_impl_call_test.cc
writer/hlsl/generator_impl_case_test.cc
writer/hlsl/generator_impl_cast_test.cc
@ -1098,8 +1100,6 @@ if(TINT_BUILD_TESTS)
writer/hlsl/generator_impl_function_test.cc
writer/hlsl/generator_impl_identifier_test.cc
writer/hlsl/generator_impl_if_test.cc
writer/hlsl/generator_impl_intrinsic_test.cc
writer/hlsl/generator_impl_intrinsic_texture_test.cc
writer/hlsl/generator_impl_import_test.cc
writer/hlsl/generator_impl_loop_test.cc
writer/hlsl/generator_impl_member_accessor_test.cc

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/intrinsic_texture_helper_test.h"
#include "src/ast/builtin_texture_helper_test.h"
#include "src/sem/depth_texture_type.h"
#include "src/sem/multisampled_texture_type.h"
@ -20,7 +20,7 @@
namespace tint {
namespace ast {
namespace intrinsic {
namespace builtin {
namespace test {
using u32 = ProgramBuilder::u32;
@ -137,11 +137,11 @@ std::ostream& operator<<(std::ostream& out, const TextureOverloadCase& data) {
const ast::Type* TextureOverloadCase::BuildResultVectorComponentType(
ProgramBuilder* b) const {
switch (texture_data_type) {
case ast::intrinsic::test::TextureDataType::kF32:
case ast::builtin::test::TextureDataType::kF32:
return b->ty.f32();
case ast::intrinsic::test::TextureDataType::kU32:
case ast::builtin::test::TextureDataType::kU32:
return b->ty.u32();
case ast::intrinsic::test::TextureDataType::kI32:
case ast::builtin::test::TextureDataType::kI32:
return b->ty.i32();
}
@ -156,29 +156,29 @@ const ast::Variable* TextureOverloadCase::BuildTextureVariable(
b->create<ast::BindingAttribute>(0),
};
switch (texture_kind) {
case ast::intrinsic::test::TextureKind::kRegular:
case ast::builtin::test::TextureKind::kRegular:
return b->Global("texture",
b->ty.sampled_texture(texture_dimension,
BuildResultVectorComponentType(b)),
attrs);
case ast::intrinsic::test::TextureKind::kDepth:
case ast::builtin::test::TextureKind::kDepth:
return b->Global("texture", b->ty.depth_texture(texture_dimension),
attrs);
case ast::intrinsic::test::TextureKind::kDepthMultisampled:
case ast::builtin::test::TextureKind::kDepthMultisampled:
return b->Global("texture",
b->ty.depth_multisampled_texture(texture_dimension),
attrs);
case ast::intrinsic::test::TextureKind::kMultisampled:
case ast::builtin::test::TextureKind::kMultisampled:
return b->Global(
"texture",
b->ty.multisampled_texture(texture_dimension,
BuildResultVectorComponentType(b)),
attrs);
case ast::intrinsic::test::TextureKind::kStorage: {
case ast::builtin::test::TextureKind::kStorage: {
auto* st = b->ty.storage_texture(texture_dimension, texel_format, access);
return b->Global("texture", st, attrs);
}
@ -2281,6 +2281,6 @@ bool ReturnsVoid(ValidTextureOverload texture_overload) {
}
} // namespace test
} // namespace intrinsic
} // namespace builtin
} // namespace ast
} // namespace tint

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_INTRINSIC_TEXTURE_HELPER_TEST_H_
#define SRC_AST_INTRINSIC_TEXTURE_HELPER_TEST_H_
#ifndef SRC_AST_BUILTIN_TEXTURE_HELPER_TEST_H_
#define SRC_AST_BUILTIN_TEXTURE_HELPER_TEST_H_
#include <vector>
@ -23,7 +23,7 @@
namespace tint {
namespace ast {
namespace intrinsic {
namespace builtin {
namespace test {
enum class TextureKind {
@ -181,10 +181,10 @@ enum class ValidTextureOverload {
};
/// @param texture_overload the ValidTextureOverload
/// @returns true if the ValidTextureOverload intrinsic returns no value.
/// @returns true if the ValidTextureOverload builtin returns no value.
bool ReturnsVoid(ValidTextureOverload texture_overload);
/// Describes a texture intrinsic overload
/// Describes a texture builtin overload
struct TextureOverloadCase {
/// Constructor for textureSample...() functions
TextureOverloadCase(ValidTextureOverload,
@ -262,8 +262,8 @@ struct TextureOverloadCase {
std::ostream& operator<<(std::ostream& out, const TextureOverloadCase& data);
} // namespace test
} // namespace intrinsic
} // namespace builtin
} // namespace ast
} // namespace tint
#endif // SRC_AST_INTRINSIC_TEXTURE_HELPER_TEST_H_
#endif // SRC_AST_BUILTIN_TEXTURE_HELPER_TEST_H_

View File

@ -26,7 +26,7 @@ class IdentifierExpression;
/// A call expression - represents either a:
/// * sem::Function
/// * sem::Intrinsic
/// * sem::Builtin
/// * sem::TypeConstructor
/// * sem::TypeConversion
class CallExpression : public Castable<CallExpression, Expression> {
@ -64,7 +64,7 @@ class CallExpression : public Castable<CallExpression, Expression> {
/// Target is either an identifier, or a Type.
/// One of these must be nullptr and the other a non-nullptr.
struct Target {
/// name is a function or intrinsic to call, or type name to construct or
/// name is a function or builtin to call, or type name to construct or
/// cast-to
const IdentifierExpression* name = nullptr;
/// type to construct or cast-to

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/intrinsic_table.h"
#include "src/builtin_table.h"
#include <algorithm>
#include <limits>
@ -286,7 +286,7 @@ class OpenNumberMatcher : public NumberMatcher {
};
////////////////////////////////////////////////////////////////////////////////
// Binding functions for use in the generated intrinsic_table.inl
// Binding functions for use in the generated builtin_table.inl
// TODO(bclayton): See if we can move more of this hand-rolled code to the
// template
////////////////////////////////////////////////////////////////////////////////
@ -793,19 +793,19 @@ struct OverloadInfo {
bool is_deprecated;
};
/// IntrinsicInfo describes an intrinsic function
struct IntrinsicInfo {
/// Number of overloads of the intrinsic function
/// BuiltinInfo describes a builtin function
struct BuiltinInfo {
/// Number of overloads of the builtin function
const uint8_t num_overloads;
/// Pointer to the start of the overloads for the function
OverloadInfo const* const overloads;
};
#include "intrinsic_table.inl"
#include "builtin_table.inl"
/// IntrinsicPrototype describes a fully matched intrinsic function, which is
/// used as a lookup for building unique sem::Intrinsic instances.
struct IntrinsicPrototype {
/// BuiltinPrototype describes a fully matched builtin function, which is
/// used as a lookup for building unique sem::Builtin instances.
struct BuiltinPrototype {
/// Parameter describes a single parameter
struct Parameter {
/// Parameter type
@ -814,11 +814,11 @@ struct IntrinsicPrototype {
ParameterUsage const usage = ParameterUsage::kNone;
};
/// Hasher provides a hash function for the IntrinsicPrototype
/// Hasher provides a hash function for the BuiltinPrototype
struct Hasher {
/// @param i the IntrinsicPrototype to create a hash for
/// @param i the BuiltinPrototype to create a hash for
/// @return the hash value
inline std::size_t operator()(const IntrinsicPrototype& i) const {
inline std::size_t operator()(const BuiltinPrototype& i) const {
size_t hash = utils::Hash(i.parameters.size());
for (auto& p : i.parameters) {
utils::HashCombine(&hash, p.type, p.usage);
@ -828,15 +828,15 @@ struct IntrinsicPrototype {
}
};
sem::IntrinsicType type = sem::IntrinsicType::kNone;
sem::BuiltinType type = sem::BuiltinType::kNone;
std::vector<Parameter> parameters;
sem::Type const* return_type = nullptr;
PipelineStageSet supported_stages;
bool is_deprecated = false;
};
/// Equality operator for IntrinsicPrototype
bool operator==(const IntrinsicPrototype& a, const IntrinsicPrototype& b) {
/// Equality operator for BuiltinPrototype
bool operator==(const BuiltinPrototype& a, const BuiltinPrototype& b) {
if (a.type != b.type || a.supported_stages != b.supported_stages ||
a.return_type != b.return_type || a.is_deprecated != b.is_deprecated ||
a.parameters.size() != b.parameters.size()) {
@ -852,20 +852,20 @@ bool operator==(const IntrinsicPrototype& a, const IntrinsicPrototype& b) {
return true;
}
/// Impl is the private implementation of the IntrinsicTable interface.
class Impl : public IntrinsicTable {
/// Impl is the private implementation of the BuiltinTable interface.
class Impl : public BuiltinTable {
public:
explicit Impl(ProgramBuilder& builder);
const sem::Intrinsic* Lookup(sem::IntrinsicType intrinsic_type,
const std::vector<const sem::Type*>& args,
const Source& source) override;
const sem::Builtin* Lookup(sem::BuiltinType builtin_type,
const std::vector<const sem::Type*>& args,
const Source& source) override;
private:
const sem::Intrinsic* Match(sem::IntrinsicType intrinsic_type,
const OverloadInfo& overload,
const std::vector<const sem::Type*>& args,
int& match_score);
const sem::Builtin* Match(sem::BuiltinType builtin_type,
const OverloadInfo& overload,
const std::vector<const sem::Type*>& args,
int& match_score);
MatchState Match(ClosedState& closed,
const OverloadInfo& overload,
@ -873,23 +873,21 @@ class Impl : public IntrinsicTable {
void PrintOverload(std::ostream& ss,
const OverloadInfo& overload,
sem::IntrinsicType intrinsic_type) const;
sem::BuiltinType builtin_type) const;
ProgramBuilder& builder;
Matchers matchers;
std::unordered_map<IntrinsicPrototype,
sem::Intrinsic*,
IntrinsicPrototype::Hasher>
intrinsics;
std::unordered_map<BuiltinPrototype, sem::Builtin*, BuiltinPrototype::Hasher>
builtins;
};
/// @return a string representing a call to an intrinsic with the given argument
/// @return a string representing a call to a builtin with the given argument
/// types.
std::string CallSignature(ProgramBuilder& builder,
sem::IntrinsicType intrinsic_type,
sem::BuiltinType builtin_type,
const std::vector<const sem::Type*>& args) {
std::stringstream ss;
ss << sem::str(intrinsic_type) << "(";
ss << sem::str(builtin_type) << "(";
{
bool first = true;
for (auto* arg : args) {
@ -915,9 +913,9 @@ std::string OpenNumberMatcher::String(MatchState& state) const {
Impl::Impl(ProgramBuilder& b) : builder(b) {}
const sem::Intrinsic* Impl::Lookup(sem::IntrinsicType intrinsic_type,
const std::vector<const sem::Type*>& args,
const Source& source) {
const sem::Builtin* Impl::Lookup(sem::BuiltinType builtin_type,
const std::vector<const sem::Type*>& args,
const Source& source) {
// Candidate holds information about a mismatched overload that could be what
// the user intended to call.
struct Candidate {
@ -928,11 +926,11 @@ const sem::Intrinsic* Impl::Lookup(sem::IntrinsicType intrinsic_type,
// The list of failed matches that had promise.
std::vector<Candidate> candidates;
auto& intrinsic = kIntrinsics[static_cast<uint32_t>(intrinsic_type)];
for (uint32_t o = 0; o < intrinsic.num_overloads; o++) {
auto& builtin = kBuiltins[static_cast<uint32_t>(builtin_type)];
for (uint32_t o = 0; o < builtin.num_overloads; o++) {
int match_score = 1000;
auto& overload = intrinsic.overloads[o];
if (auto* match = Match(intrinsic_type, overload, args, match_score)) {
auto& overload = builtin.overloads[o];
if (auto* match = Match(builtin_type, overload, args, match_score)) {
return match;
}
if (match_score > 0) {
@ -947,7 +945,7 @@ const sem::Intrinsic* Impl::Lookup(sem::IntrinsicType intrinsic_type,
// Generate an error message
std::stringstream ss;
ss << "no matching call to " << CallSignature(builder, intrinsic_type, args)
ss << "no matching call to " << CallSignature(builder, builtin_type, args)
<< std::endl;
if (!candidates.empty()) {
ss << std::endl;
@ -955,7 +953,7 @@ const sem::Intrinsic* Impl::Lookup(sem::IntrinsicType intrinsic_type,
<< (candidates.size() > 1 ? "s:" : ":") << std::endl;
for (auto& candidate : candidates) {
ss << " ";
PrintOverload(ss, *candidate.overload, intrinsic_type);
PrintOverload(ss, *candidate.overload, builtin_type);
ss << std::endl;
}
}
@ -963,10 +961,10 @@ const sem::Intrinsic* Impl::Lookup(sem::IntrinsicType intrinsic_type,
return nullptr;
}
const sem::Intrinsic* Impl::Match(sem::IntrinsicType intrinsic_type,
const OverloadInfo& overload,
const std::vector<const sem::Type*>& args,
int& match_score) {
const sem::Builtin* Impl::Match(sem::BuiltinType builtin_type,
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;
@ -987,7 +985,7 @@ const sem::Intrinsic* Impl::Match(sem::IntrinsicType intrinsic_type,
ClosedState closed(builder);
std::vector<IntrinsicPrototype::Parameter> parameters;
std::vector<BuiltinPrototype::Parameter> parameters;
auto num_params = std::min(num_parameters, num_arguments);
for (uint32_t p = 0; p < num_params; p++) {
@ -996,7 +994,7 @@ const sem::Intrinsic* Impl::Match(sem::IntrinsicType intrinsic_type,
auto* type = Match(closed, overload, indices).Type(args[p]->UnwrapRef());
if (type) {
parameters.emplace_back(
IntrinsicPrototype::Parameter{type, parameter.usage});
BuiltinPrototype::Parameter{type, parameter.usage});
match_score += kScorePerMatchedParam;
} else {
overload_matched = false;
@ -1044,7 +1042,7 @@ const sem::Intrinsic* Impl::Match(sem::IntrinsicType intrinsic_type,
return_type = Match(closed, overload, indices).Type(&any);
if (!return_type) {
std::stringstream ss;
PrintOverload(ss, overload, intrinsic_type);
PrintOverload(ss, overload, builtin_type);
TINT_ICE(Resolver, builder.Diagnostics())
<< "MatchState.Match() returned null for " << ss.str();
return nullptr;
@ -1053,25 +1051,25 @@ const sem::Intrinsic* Impl::Match(sem::IntrinsicType intrinsic_type,
return_type = builder.create<sem::Void>();
}
IntrinsicPrototype intrinsic;
intrinsic.type = intrinsic_type;
intrinsic.return_type = return_type;
intrinsic.parameters = std::move(parameters);
intrinsic.supported_stages = overload.supported_stages;
intrinsic.is_deprecated = overload.is_deprecated;
BuiltinPrototype builtin;
builtin.type = builtin_type;
builtin.return_type = return_type;
builtin.parameters = std::move(parameters);
builtin.supported_stages = overload.supported_stages;
builtin.is_deprecated = overload.is_deprecated;
// De-duplicate intrinsics that are identical.
return utils::GetOrCreate(intrinsics, intrinsic, [&] {
// De-duplicate builtins that are identical.
return utils::GetOrCreate(builtins, builtin, [&] {
std::vector<sem::Parameter*> params;
params.reserve(intrinsic.parameters.size());
for (auto& p : intrinsic.parameters) {
params.reserve(builtin.parameters.size());
for (auto& p : builtin.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::Intrinsic>(
intrinsic.type, intrinsic.return_type, std::move(params),
intrinsic.supported_stages, intrinsic.is_deprecated);
return builder.create<sem::Builtin>(
builtin.type, builtin.return_type, std::move(params),
builtin.supported_stages, builtin.is_deprecated);
});
}
@ -1083,10 +1081,10 @@ MatchState Impl::Match(ClosedState& closed,
void Impl::PrintOverload(std::ostream& ss,
const OverloadInfo& overload,
sem::IntrinsicType intrinsic_type) const {
sem::BuiltinType builtin_type) const {
ClosedState closed(builder);
ss << intrinsic_type << "(";
ss << builtin_type << "(";
for (uint32_t p = 0; p < overload.num_parameters; p++) {
auto& parameter = overload.parameters[p];
if (p > 0) {
@ -1156,12 +1154,11 @@ std::string MatchState::NumName() {
} // namespace
std::unique_ptr<IntrinsicTable> IntrinsicTable::Create(
ProgramBuilder& builder) {
std::unique_ptr<BuiltinTable> BuiltinTable::Create(ProgramBuilder& builder) {
return std::make_unique<Impl>(builder);
}
IntrinsicTable::~IntrinsicTable() = default;
BuiltinTable::~BuiltinTable() = default;
/// TypeInfo for the Any type declared in the anonymous namespace above
TINT_INSTANTIATE_TYPEINFO(Any);

52
src/builtin_table.h Normal file
View File

@ -0,0 +1,52 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_BUILTIN_TABLE_H_
#define SRC_BUILTIN_TABLE_H_
#include <memory>
#include <string>
#include <vector>
#include "src/sem/builtin.h"
namespace tint {
// Forward declarations
class ProgramBuilder;
/// BuiltinTable is a lookup table of all the WGSL builtin functions
class BuiltinTable {
public:
/// @param builder the program builder
/// @return a pointer to a newly created BuiltinTable
static std::unique_ptr<BuiltinTable> Create(ProgramBuilder& builder);
/// Destructor
virtual ~BuiltinTable();
/// Lookup looks for the builtin overload with the given signature, raising
/// an error diagnostic if the builtin was not found.
/// @param type the builtin type
/// @param args the argument types passed to the builtin function
/// @param source the source of the builtin call
/// @return the semantic builtin if found, otherwise nullptr
virtual const sem::Builtin* Lookup(sem::BuiltinType type,
const std::vector<const sem::Type*>& args,
const Source& source) = 0;
};
} // namespace tint
#endif // SRC_BUILTIN_TABLE_H_

View File

@ -13,11 +13,11 @@
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// File generated by tools/intrinsic-gen
// File generated by tools/builtin-gen
// using the template:
// src/intrinsic_table.inl.tmpl
// and the intrinsic defintion file:
// src/intrinsics.def
// src/builtin_table.inl.tmpl
// and the builtin defintion file:
// src/builtins.def
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
@ -25,7 +25,7 @@
// clang-format off
/// TypeMatcher for 'type bool'
/// @see src/intrinsics.def:68:6
/// @see src/builtins.def:68:6
class Bool : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -52,7 +52,7 @@ std::string Bool::String(MatchState&) const {
}
/// TypeMatcher for 'type f32'
/// @see src/intrinsics.def:69:6
/// @see src/builtins.def:69:6
class F32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -79,7 +79,7 @@ std::string F32::String(MatchState&) const {
}
/// TypeMatcher for 'type i32'
/// @see src/intrinsics.def:70:6
/// @see src/builtins.def:70:6
class I32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -106,7 +106,7 @@ std::string I32::String(MatchState&) const {
}
/// TypeMatcher for 'type u32'
/// @see src/intrinsics.def:71:6
/// @see src/builtins.def:71:6
class U32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -133,7 +133,7 @@ std::string U32::String(MatchState&) const {
}
/// TypeMatcher for 'type vec2'
/// @see src/intrinsics.def:72:6
/// @see src/builtins.def:72:6
class Vec2 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -166,7 +166,7 @@ std::string Vec2::String(MatchState& state) const {
}
/// TypeMatcher for 'type vec3'
/// @see src/intrinsics.def:73:6
/// @see src/builtins.def:73:6
class Vec3 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -199,7 +199,7 @@ std::string Vec3::String(MatchState& state) const {
}
/// TypeMatcher for 'type vec4'
/// @see src/intrinsics.def:74:6
/// @see src/builtins.def:74:6
class Vec4 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -232,7 +232,7 @@ std::string Vec4::String(MatchState& state) const {
}
/// TypeMatcher for 'type vec'
/// @see src/intrinsics.def:75:37
/// @see src/builtins.def:75:37
class Vec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -273,7 +273,7 @@ std::string Vec::String(MatchState& state) const {
}
/// TypeMatcher for 'type mat'
/// @see src/intrinsics.def:76:37
/// @see src/builtins.def:76:37
class Mat : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -320,7 +320,7 @@ std::string Mat::String(MatchState& state) const {
}
/// TypeMatcher for 'type ptr'
/// @see src/intrinsics.def:77:6
/// @see src/builtins.def:77:6
class Ptr : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -365,7 +365,7 @@ std::string Ptr::String(MatchState& state) const {
}
/// TypeMatcher for 'type atomic'
/// @see src/intrinsics.def:78:6
/// @see src/builtins.def:78:6
class Atomic : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -398,7 +398,7 @@ std::string Atomic::String(MatchState& state) const {
}
/// TypeMatcher for 'type array'
/// @see src/intrinsics.def:79:6
/// @see src/builtins.def:79:6
class Array : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -431,7 +431,7 @@ std::string Array::String(MatchState& state) const {
}
/// TypeMatcher for 'type sampler'
/// @see src/intrinsics.def:80:6
/// @see src/builtins.def:80:6
class Sampler : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -458,7 +458,7 @@ std::string Sampler::String(MatchState&) const {
}
/// TypeMatcher for 'type sampler_comparison'
/// @see src/intrinsics.def:81:6
/// @see src/builtins.def:81:6
class SamplerComparison : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -485,7 +485,7 @@ std::string SamplerComparison::String(MatchState&) const {
}
/// TypeMatcher for 'type texture_1d'
/// @see src/intrinsics.def:82:6
/// @see src/builtins.def:82:6
class Texture1D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -518,7 +518,7 @@ std::string Texture1D::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_2d'
/// @see src/intrinsics.def:83:6
/// @see src/builtins.def:83:6
class Texture2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -551,7 +551,7 @@ std::string Texture2D::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_2d_array'
/// @see src/intrinsics.def:84:6
/// @see src/builtins.def:84:6
class Texture2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -584,7 +584,7 @@ std::string Texture2DArray::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_3d'
/// @see src/intrinsics.def:85:6
/// @see src/builtins.def:85:6
class Texture3D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -617,7 +617,7 @@ std::string Texture3D::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_cube'
/// @see src/intrinsics.def:86:6
/// @see src/builtins.def:86:6
class TextureCube : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -650,7 +650,7 @@ std::string TextureCube::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_cube_array'
/// @see src/intrinsics.def:87:6
/// @see src/builtins.def:87:6
class TextureCubeArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -683,7 +683,7 @@ std::string TextureCubeArray::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_multisampled_2d'
/// @see src/intrinsics.def:88:6
/// @see src/builtins.def:88:6
class TextureMultisampled2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -716,7 +716,7 @@ std::string TextureMultisampled2D::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_depth_2d'
/// @see src/intrinsics.def:89:6
/// @see src/builtins.def:89:6
class TextureDepth2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -743,7 +743,7 @@ std::string TextureDepth2D::String(MatchState&) const {
}
/// TypeMatcher for 'type texture_depth_2d_array'
/// @see src/intrinsics.def:90:6
/// @see src/builtins.def:90:6
class TextureDepth2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -770,7 +770,7 @@ std::string TextureDepth2DArray::String(MatchState&) const {
}
/// TypeMatcher for 'type texture_depth_cube'
/// @see src/intrinsics.def:91:6
/// @see src/builtins.def:91:6
class TextureDepthCube : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -797,7 +797,7 @@ std::string TextureDepthCube::String(MatchState&) const {
}
/// TypeMatcher for 'type texture_depth_cube_array'
/// @see src/intrinsics.def:92:6
/// @see src/builtins.def:92:6
class TextureDepthCubeArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -824,7 +824,7 @@ std::string TextureDepthCubeArray::String(MatchState&) const {
}
/// TypeMatcher for 'type texture_depth_multisampled_2d'
/// @see src/intrinsics.def:93:6
/// @see src/builtins.def:93:6
class TextureDepthMultisampled2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -851,7 +851,7 @@ std::string TextureDepthMultisampled2D::String(MatchState&) const {
}
/// TypeMatcher for 'type texture_storage_1d'
/// @see src/intrinsics.def:94:6
/// @see src/builtins.def:94:6
class TextureStorage1D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -890,7 +890,7 @@ std::string TextureStorage1D::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_storage_2d'
/// @see src/intrinsics.def:95:6
/// @see src/builtins.def:95:6
class TextureStorage2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -929,7 +929,7 @@ std::string TextureStorage2D::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_storage_2d_array'
/// @see src/intrinsics.def:96:6
/// @see src/builtins.def:96:6
class TextureStorage2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -968,7 +968,7 @@ std::string TextureStorage2DArray::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_storage_3d'
/// @see src/intrinsics.def:97:6
/// @see src/builtins.def:97:6
class TextureStorage3D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -1007,7 +1007,7 @@ std::string TextureStorage3D::String(MatchState& state) const {
}
/// TypeMatcher for 'type texture_external'
/// @see src/intrinsics.def:98:6
/// @see src/builtins.def:98:6
class TextureExternal : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -1034,7 +1034,7 @@ std::string TextureExternal::String(MatchState&) const {
}
/// TypeMatcher for 'type __modf_result'
/// @see src/intrinsics.def:100:6
/// @see src/builtins.def:100:6
class ModfResult : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -1061,7 +1061,7 @@ std::string ModfResult::String(MatchState&) const {
}
/// TypeMatcher for 'type __modf_result_vec'
/// @see src/intrinsics.def:101:42
/// @see src/builtins.def:101:42
class ModfResultVec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -1096,7 +1096,7 @@ std::string ModfResultVec::String(MatchState& state) const {
}
/// TypeMatcher for 'type __frexp_result'
/// @see src/intrinsics.def:102:6
/// @see src/builtins.def:102:6
class FrexpResult : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -1123,7 +1123,7 @@ std::string FrexpResult::String(MatchState&) const {
}
/// TypeMatcher for 'type __frexp_result_vec'
/// @see src/intrinsics.def:103:43
/// @see src/builtins.def:103:43
class FrexpResultVec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@ -1158,7 +1158,7 @@ std::string FrexpResultVec::String(MatchState& state) const {
}
/// TypeMatcher for 'match fiu32'
/// @see src/intrinsics.def:111:7
/// @see src/builtins.def:111:7
class Fiu32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@ -1192,7 +1192,7 @@ std::string Fiu32::String(MatchState&) const {
}
/// TypeMatcher for 'match iu32'
/// @see src/intrinsics.def:112:7
/// @see src/builtins.def:112:7
class Iu32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@ -1223,7 +1223,7 @@ std::string Iu32::String(MatchState&) const {
}
/// TypeMatcher for 'match scalar'
/// @see src/intrinsics.def:113:7
/// @see src/builtins.def:113:7
class Scalar : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@ -1260,7 +1260,7 @@ std::string Scalar::String(MatchState&) const {
}
/// EnumMatcher for 'match f32_texel_format'
/// @see src/intrinsics.def:124:7
/// @see src/builtins.def:124:7
class F32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@ -1293,7 +1293,7 @@ std::string F32TexelFormat::String(MatchState&) const {
}
/// EnumMatcher for 'match i32_texel_format'
/// @see src/intrinsics.def:126:7
/// @see src/builtins.def:126:7
class I32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@ -1325,7 +1325,7 @@ std::string I32TexelFormat::String(MatchState&) const {
}
/// EnumMatcher for 'match u32_texel_format'
/// @see src/intrinsics.def:128:7
/// @see src/builtins.def:128:7
class U32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@ -1357,7 +1357,7 @@ std::string U32TexelFormat::String(MatchState&) const {
}
/// EnumMatcher for 'match write_only'
/// @see src/intrinsics.def:131:7
/// @see src/builtins.def:131:7
class WriteOnly : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@ -1383,7 +1383,7 @@ std::string WriteOnly::String(MatchState&) const {
}
/// EnumMatcher for 'match function_private_workgroup'
/// @see src/intrinsics.def:133:7
/// @see src/builtins.def:133:7
class FunctionPrivateWorkgroup : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@ -1413,7 +1413,7 @@ std::string FunctionPrivateWorkgroup::String(MatchState&) const {
}
/// EnumMatcher for 'match workgroup_or_storage'
/// @see src/intrinsics.def:134:7
/// @see src/builtins.def:134:7
class WorkgroupOrStorage : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@ -8642,7 +8642,7 @@ constexpr OverloadInfo kOverloads[] = {
},
};
constexpr IntrinsicInfo kIntrinsics[] = {
constexpr BuiltinInfo kBuiltins[] = {
{
/* [0] */
/* fn abs<T : fiu32>(T) -> T */

View File

@ -1,10 +1,10 @@
{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/intrinsic-gen to generate intrinsic_table.inl
Used by IntrinsicTable.cc for intrinsic overload resolution.
Template file for use with tools/builtin-gen to generate builtin_table.inl
Used by BuiltinTable.cc for builtin overload resolution.
See:
* tools/cmd/intrinsic-gen/gen for structures used by this template
* tools/cmd/builtin-gen/gen for structures used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}
@ -23,7 +23,7 @@ See:
{{ end -}}
{{- end -}}
{{- with IntrinsicTable -}}
{{- with BuiltinTable -}}
{{- template "Matchers" . }}
constexpr MatcherIndex kMatcherIndices[] = {
@ -106,7 +106,7 @@ constexpr OverloadInfo kOverloads[] = {
{{- end }}
};
constexpr IntrinsicInfo kIntrinsics[] = {
constexpr BuiltinInfo kBuiltins[] = {
{{- range $i, $f := .Functions }}
{
/* [{{$i}}] */

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/intrinsic_table.h"
#include "src/builtin_table.h"
#include "gmock/gmock.h"
#include "src/program_builder.h"
@ -30,65 +30,63 @@ namespace {
using ::testing::HasSubstr;
using IntrinsicType = sem::IntrinsicType;
using BuiltinType = sem::BuiltinType;
using Parameter = sem::Parameter;
using ParameterUsage = sem::ParameterUsage;
class IntrinsicTableTest : public testing::Test, public ProgramBuilder {
class BuiltinTableTest : public testing::Test, public ProgramBuilder {
public:
std::unique_ptr<IntrinsicTable> table = IntrinsicTable::Create(*this);
std::unique_ptr<BuiltinTable> table = BuiltinTable::Create(*this);
};
TEST_F(IntrinsicTableTest, MatchF32) {
TEST_F(BuiltinTableTest, MatchF32) {
auto* f32 = create<sem::F32>();
auto* result = table->Lookup(IntrinsicType::kCos, {f32}, Source{});
auto* result = table->Lookup(BuiltinType::kCos, {f32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kCos);
EXPECT_EQ(result->Type(), BuiltinType::kCos);
EXPECT_EQ(result->ReturnType(), f32);
ASSERT_EQ(result->Parameters().size(), 1u);
EXPECT_EQ(result->Parameters()[0]->Type(), f32);
}
TEST_F(IntrinsicTableTest, MismatchF32) {
TEST_F(BuiltinTableTest, MismatchF32) {
auto* i32 = create<sem::I32>();
auto* result = table->Lookup(IntrinsicType::kCos, {i32}, Source{});
auto* result = table->Lookup(BuiltinType::kCos, {i32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchU32) {
TEST_F(BuiltinTableTest, MatchU32) {
auto* f32 = create<sem::F32>();
auto* u32 = create<sem::U32>();
auto* vec2_f32 = create<sem::Vector>(f32, 2);
auto* result =
table->Lookup(IntrinsicType::kUnpack2x16float, {u32}, Source{});
auto* result = table->Lookup(BuiltinType::kUnpack2x16float, {u32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kUnpack2x16float);
EXPECT_EQ(result->Type(), BuiltinType::kUnpack2x16float);
EXPECT_EQ(result->ReturnType(), vec2_f32);
ASSERT_EQ(result->Parameters().size(), 1u);
EXPECT_EQ(result->Parameters()[0]->Type(), u32);
}
TEST_F(IntrinsicTableTest, MismatchU32) {
TEST_F(BuiltinTableTest, MismatchU32) {
auto* f32 = create<sem::F32>();
auto* result =
table->Lookup(IntrinsicType::kUnpack2x16float, {f32}, Source{});
auto* result = table->Lookup(BuiltinType::kUnpack2x16float, {f32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchI32) {
TEST_F(BuiltinTableTest, MatchI32) {
auto* f32 = create<sem::F32>();
auto* i32 = create<sem::I32>();
auto* vec4_f32 = create<sem::Vector>(f32, 4);
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k1d, f32);
auto* result =
table->Lookup(IntrinsicType::kTextureLoad, {tex, i32, i32}, Source{});
table->Lookup(BuiltinType::kTextureLoad, {tex, i32, i32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kTextureLoad);
EXPECT_EQ(result->Type(), BuiltinType::kTextureLoad);
EXPECT_EQ(result->ReturnType(), vec4_f32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), tex);
@ -99,51 +97,49 @@ TEST_F(IntrinsicTableTest, MatchI32) {
EXPECT_EQ(result->Parameters()[2]->Usage(), ParameterUsage::kLevel);
}
TEST_F(IntrinsicTableTest, MismatchI32) {
TEST_F(BuiltinTableTest, MismatchI32) {
auto* f32 = create<sem::F32>();
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k1d, f32);
auto* result =
table->Lookup(IntrinsicType::kTextureLoad, {tex, f32}, Source{});
auto* result = table->Lookup(BuiltinType::kTextureLoad, {tex, f32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchIU32AsI32) {
TEST_F(BuiltinTableTest, MatchIU32AsI32) {
auto* i32 = create<sem::I32>();
auto* result = table->Lookup(IntrinsicType::kCountOneBits, {i32}, Source{});
auto* result = table->Lookup(BuiltinType::kCountOneBits, {i32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kCountOneBits);
EXPECT_EQ(result->Type(), BuiltinType::kCountOneBits);
EXPECT_EQ(result->ReturnType(), i32);
ASSERT_EQ(result->Parameters().size(), 1u);
EXPECT_EQ(result->Parameters()[0]->Type(), i32);
}
TEST_F(IntrinsicTableTest, MatchIU32AsU32) {
TEST_F(BuiltinTableTest, MatchIU32AsU32) {
auto* u32 = create<sem::U32>();
auto* result = table->Lookup(IntrinsicType::kCountOneBits, {u32}, Source{});
auto* result = table->Lookup(BuiltinType::kCountOneBits, {u32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kCountOneBits);
EXPECT_EQ(result->Type(), BuiltinType::kCountOneBits);
EXPECT_EQ(result->ReturnType(), u32);
ASSERT_EQ(result->Parameters().size(), 1u);
EXPECT_EQ(result->Parameters()[0]->Type(), u32);
}
TEST_F(IntrinsicTableTest, MismatchIU32) {
TEST_F(BuiltinTableTest, MismatchIU32) {
auto* f32 = create<sem::F32>();
auto* result = table->Lookup(IntrinsicType::kCountOneBits, {f32}, Source{});
auto* result = table->Lookup(BuiltinType::kCountOneBits, {f32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchFIU32AsI32) {
TEST_F(BuiltinTableTest, MatchFIU32AsI32) {
auto* i32 = create<sem::I32>();
auto* result =
table->Lookup(IntrinsicType::kClamp, {i32, i32, i32}, Source{});
auto* result = table->Lookup(BuiltinType::kClamp, {i32, i32, i32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kClamp);
EXPECT_EQ(result->Type(), BuiltinType::kClamp);
EXPECT_EQ(result->ReturnType(), i32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), i32);
@ -151,13 +147,12 @@ TEST_F(IntrinsicTableTest, MatchFIU32AsI32) {
EXPECT_EQ(result->Parameters()[2]->Type(), i32);
}
TEST_F(IntrinsicTableTest, MatchFIU32AsU32) {
TEST_F(BuiltinTableTest, MatchFIU32AsU32) {
auto* u32 = create<sem::U32>();
auto* result =
table->Lookup(IntrinsicType::kClamp, {u32, u32, u32}, Source{});
auto* result = table->Lookup(BuiltinType::kClamp, {u32, u32, u32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kClamp);
EXPECT_EQ(result->Type(), BuiltinType::kClamp);
EXPECT_EQ(result->ReturnType(), u32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), u32);
@ -165,13 +160,12 @@ TEST_F(IntrinsicTableTest, MatchFIU32AsU32) {
EXPECT_EQ(result->Parameters()[2]->Type(), u32);
}
TEST_F(IntrinsicTableTest, MatchFIU32AsF32) {
TEST_F(BuiltinTableTest, MatchFIU32AsF32) {
auto* f32 = create<sem::F32>();
auto* result =
table->Lookup(IntrinsicType::kClamp, {f32, f32, f32}, Source{});
auto* result = table->Lookup(BuiltinType::kClamp, {f32, f32, f32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kClamp);
EXPECT_EQ(result->Type(), BuiltinType::kClamp);
EXPECT_EQ(result->ReturnType(), f32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), f32);
@ -179,22 +173,22 @@ TEST_F(IntrinsicTableTest, MatchFIU32AsF32) {
EXPECT_EQ(result->Parameters()[2]->Type(), f32);
}
TEST_F(IntrinsicTableTest, MismatchFIU32) {
TEST_F(BuiltinTableTest, MismatchFIU32) {
auto* bool_ = create<sem::Bool>();
auto* result =
table->Lookup(IntrinsicType::kClamp, {bool_, bool_, bool_}, Source{});
table->Lookup(BuiltinType::kClamp, {bool_, bool_, bool_}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchBool) {
TEST_F(BuiltinTableTest, MatchBool) {
auto* f32 = create<sem::F32>();
auto* bool_ = create<sem::Bool>();
auto* result =
table->Lookup(IntrinsicType::kSelect, {f32, f32, bool_}, Source{});
table->Lookup(BuiltinType::kSelect, {f32, f32, bool_}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kSelect);
EXPECT_EQ(result->Type(), BuiltinType::kSelect);
EXPECT_EQ(result->ReturnType(), f32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), f32);
@ -202,46 +196,43 @@ TEST_F(IntrinsicTableTest, MatchBool) {
EXPECT_EQ(result->Parameters()[2]->Type(), bool_);
}
TEST_F(IntrinsicTableTest, MismatchBool) {
TEST_F(BuiltinTableTest, MismatchBool) {
auto* f32 = create<sem::F32>();
auto* result =
table->Lookup(IntrinsicType::kSelect, {f32, f32, f32}, Source{});
auto* result = table->Lookup(BuiltinType::kSelect, {f32, f32, f32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchPointer) {
TEST_F(BuiltinTableTest, MatchPointer) {
auto* i32 = create<sem::I32>();
auto* atomicI32 = create<sem::Atomic>(i32);
auto* ptr = create<sem::Pointer>(atomicI32, ast::StorageClass::kWorkgroup,
ast::Access::kReadWrite);
auto* result = table->Lookup(IntrinsicType::kAtomicLoad, {ptr}, Source{});
auto* result = table->Lookup(BuiltinType::kAtomicLoad, {ptr}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kAtomicLoad);
EXPECT_EQ(result->Type(), BuiltinType::kAtomicLoad);
EXPECT_EQ(result->ReturnType(), i32);
ASSERT_EQ(result->Parameters().size(), 1u);
EXPECT_EQ(result->Parameters()[0]->Type(), ptr);
}
TEST_F(IntrinsicTableTest, MismatchPointer) {
TEST_F(BuiltinTableTest, MismatchPointer) {
auto* i32 = create<sem::I32>();
auto* atomicI32 = create<sem::Atomic>(i32);
auto* result =
table->Lookup(IntrinsicType::kAtomicLoad, {atomicI32}, Source{});
auto* result = table->Lookup(BuiltinType::kAtomicLoad, {atomicI32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchArray) {
TEST_F(BuiltinTableTest, MatchArray) {
auto* arr = create<sem::Array>(create<sem::U32>(), 0, 4, 4, 4, 4);
auto* arr_ptr = create<sem::Pointer>(arr, ast::StorageClass::kStorage,
ast::Access::kReadWrite);
auto* result =
table->Lookup(IntrinsicType::kArrayLength, {arr_ptr}, Source{});
auto* result = table->Lookup(BuiltinType::kArrayLength, {arr_ptr}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kArrayLength);
EXPECT_EQ(result->Type(), BuiltinType::kArrayLength);
EXPECT_TRUE(result->ReturnType()->Is<sem::U32>());
ASSERT_EQ(result->Parameters().size(), 1u);
auto* param_type = result->Parameters()[0]->Type();
@ -249,24 +240,24 @@ TEST_F(IntrinsicTableTest, MatchArray) {
EXPECT_TRUE(param_type->As<sem::Pointer>()->StoreType()->Is<sem::Array>());
}
TEST_F(IntrinsicTableTest, MismatchArray) {
TEST_F(BuiltinTableTest, MismatchArray) {
auto* f32 = create<sem::F32>();
auto* result = table->Lookup(IntrinsicType::kArrayLength, {f32}, Source{});
auto* result = table->Lookup(BuiltinType::kArrayLength, {f32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchSampler) {
TEST_F(BuiltinTableTest, MatchSampler) {
auto* f32 = create<sem::F32>();
auto* vec2_f32 = create<sem::Vector>(f32, 2);
auto* vec4_f32 = create<sem::Vector>(f32, 4);
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k2d, f32);
auto* sampler = create<sem::Sampler>(ast::SamplerKind::kSampler);
auto* result = table->Lookup(IntrinsicType::kTextureSample,
auto* result = table->Lookup(BuiltinType::kTextureSample,
{tex, sampler, vec2_f32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kTextureSample);
EXPECT_EQ(result->Type(), BuiltinType::kTextureSample);
EXPECT_EQ(result->ReturnType(), vec4_f32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), tex);
@ -277,27 +268,27 @@ TEST_F(IntrinsicTableTest, MatchSampler) {
EXPECT_EQ(result->Parameters()[2]->Usage(), ParameterUsage::kCoords);
}
TEST_F(IntrinsicTableTest, MismatchSampler) {
TEST_F(BuiltinTableTest, MismatchSampler) {
auto* f32 = create<sem::F32>();
auto* vec2_f32 = create<sem::Vector>(f32, 2);
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k2d, f32);
auto* result = table->Lookup(IntrinsicType::kTextureSample,
auto* result = table->Lookup(BuiltinType::kTextureSample,
{tex, f32, vec2_f32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchSampledTexture) {
TEST_F(BuiltinTableTest, MatchSampledTexture) {
auto* i32 = create<sem::I32>();
auto* f32 = create<sem::F32>();
auto* vec2_i32 = create<sem::Vector>(i32, 2);
auto* vec4_f32 = create<sem::Vector>(f32, 4);
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k2d, f32);
auto* result = table->Lookup(IntrinsicType::kTextureLoad,
{tex, vec2_i32, i32}, Source{});
auto* result =
table->Lookup(BuiltinType::kTextureLoad, {tex, vec2_i32, i32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kTextureLoad);
EXPECT_EQ(result->Type(), BuiltinType::kTextureLoad);
EXPECT_EQ(result->ReturnType(), vec4_f32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), tex);
@ -308,17 +299,17 @@ TEST_F(IntrinsicTableTest, MatchSampledTexture) {
EXPECT_EQ(result->Parameters()[2]->Usage(), ParameterUsage::kLevel);
}
TEST_F(IntrinsicTableTest, MatchMultisampledTexture) {
TEST_F(BuiltinTableTest, MatchMultisampledTexture) {
auto* i32 = create<sem::I32>();
auto* f32 = create<sem::F32>();
auto* vec2_i32 = create<sem::Vector>(i32, 2);
auto* vec4_f32 = create<sem::Vector>(f32, 4);
auto* tex = create<sem::MultisampledTexture>(ast::TextureDimension::k2d, f32);
auto* result = table->Lookup(IntrinsicType::kTextureLoad,
{tex, vec2_i32, i32}, Source{});
auto* result =
table->Lookup(BuiltinType::kTextureLoad, {tex, vec2_i32, i32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kTextureLoad);
EXPECT_EQ(result->Type(), BuiltinType::kTextureLoad);
EXPECT_EQ(result->ReturnType(), vec4_f32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), tex);
@ -329,16 +320,16 @@ TEST_F(IntrinsicTableTest, MatchMultisampledTexture) {
EXPECT_EQ(result->Parameters()[2]->Usage(), ParameterUsage::kSampleIndex);
}
TEST_F(IntrinsicTableTest, MatchDepthTexture) {
TEST_F(BuiltinTableTest, MatchDepthTexture) {
auto* f32 = create<sem::F32>();
auto* i32 = create<sem::I32>();
auto* vec2_i32 = create<sem::Vector>(i32, 2);
auto* tex = create<sem::DepthTexture>(ast::TextureDimension::k2d);
auto* result = table->Lookup(IntrinsicType::kTextureLoad,
{tex, vec2_i32, i32}, Source{});
auto* result =
table->Lookup(BuiltinType::kTextureLoad, {tex, vec2_i32, i32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kTextureLoad);
EXPECT_EQ(result->Type(), BuiltinType::kTextureLoad);
EXPECT_EQ(result->ReturnType(), f32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), tex);
@ -349,16 +340,16 @@ TEST_F(IntrinsicTableTest, MatchDepthTexture) {
EXPECT_EQ(result->Parameters()[2]->Usage(), ParameterUsage::kLevel);
}
TEST_F(IntrinsicTableTest, MatchDepthMultisampledTexture) {
TEST_F(BuiltinTableTest, MatchDepthMultisampledTexture) {
auto* f32 = create<sem::F32>();
auto* i32 = create<sem::I32>();
auto* vec2_i32 = create<sem::Vector>(i32, 2);
auto* tex = create<sem::DepthMultisampledTexture>(ast::TextureDimension::k2d);
auto* result = table->Lookup(IntrinsicType::kTextureLoad,
{tex, vec2_i32, i32}, Source{});
auto* result =
table->Lookup(BuiltinType::kTextureLoad, {tex, vec2_i32, i32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kTextureLoad);
EXPECT_EQ(result->Type(), BuiltinType::kTextureLoad);
EXPECT_EQ(result->ReturnType(), f32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), tex);
@ -369,17 +360,17 @@ TEST_F(IntrinsicTableTest, MatchDepthMultisampledTexture) {
EXPECT_EQ(result->Parameters()[2]->Usage(), ParameterUsage::kSampleIndex);
}
TEST_F(IntrinsicTableTest, MatchExternalTexture) {
TEST_F(BuiltinTableTest, MatchExternalTexture) {
auto* f32 = create<sem::F32>();
auto* i32 = create<sem::I32>();
auto* vec2_i32 = create<sem::Vector>(i32, 2);
auto* vec4_f32 = create<sem::Vector>(f32, 4);
auto* tex = create<sem::ExternalTexture>();
auto* result =
table->Lookup(IntrinsicType::kTextureLoad, {tex, vec2_i32}, Source{});
table->Lookup(BuiltinType::kTextureLoad, {tex, vec2_i32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kTextureLoad);
EXPECT_EQ(result->Type(), BuiltinType::kTextureLoad);
EXPECT_EQ(result->ReturnType(), vec4_f32);
ASSERT_EQ(result->Parameters().size(), 2u);
EXPECT_EQ(result->Parameters()[0]->Type(), tex);
@ -388,7 +379,7 @@ TEST_F(IntrinsicTableTest, MatchExternalTexture) {
EXPECT_EQ(result->Parameters()[1]->Usage(), ParameterUsage::kCoords);
}
TEST_F(IntrinsicTableTest, MatchWOStorageTexture) {
TEST_F(BuiltinTableTest, MatchWOStorageTexture) {
auto* f32 = create<sem::F32>();
auto* i32 = create<sem::I32>();
auto* vec2_i32 = create<sem::Vector>(i32, 2);
@ -399,11 +390,11 @@ TEST_F(IntrinsicTableTest, MatchWOStorageTexture) {
ast::TexelFormat::kR32Float,
ast::Access::kWrite, subtype);
auto* result = table->Lookup(IntrinsicType::kTextureStore,
auto* result = table->Lookup(BuiltinType::kTextureStore,
{tex, vec2_i32, vec4_f32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kTextureStore);
EXPECT_EQ(result->Type(), BuiltinType::kTextureStore);
EXPECT_TRUE(result->ReturnType()->Is<sem::Void>());
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), tex);
@ -414,61 +405,59 @@ TEST_F(IntrinsicTableTest, MatchWOStorageTexture) {
EXPECT_EQ(result->Parameters()[2]->Usage(), ParameterUsage::kValue);
}
TEST_F(IntrinsicTableTest, MismatchTexture) {
TEST_F(BuiltinTableTest, MismatchTexture) {
auto* f32 = create<sem::F32>();
auto* i32 = create<sem::I32>();
auto* vec2_i32 = create<sem::Vector>(i32, 2);
auto* result =
table->Lookup(IntrinsicType::kTextureLoad, {f32, vec2_i32}, Source{});
table->Lookup(BuiltinType::kTextureLoad, {f32, vec2_i32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, ImplicitLoadOnReference) {
TEST_F(BuiltinTableTest, ImplicitLoadOnReference) {
auto* f32 = create<sem::F32>();
auto* result =
table->Lookup(IntrinsicType::kCos,
table->Lookup(BuiltinType::kCos,
{create<sem::Reference>(f32, ast::StorageClass::kFunction,
ast::Access::kReadWrite)},
Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kCos);
EXPECT_EQ(result->Type(), BuiltinType::kCos);
EXPECT_EQ(result->ReturnType(), f32);
ASSERT_EQ(result->Parameters().size(), 1u);
EXPECT_EQ(result->Parameters()[0]->Type(), f32);
}
TEST_F(IntrinsicTableTest, MatchOpenType) {
TEST_F(BuiltinTableTest, MatchOpenType) {
auto* f32 = create<sem::F32>();
auto* result =
table->Lookup(IntrinsicType::kClamp, {f32, f32, f32}, Source{});
auto* result = table->Lookup(BuiltinType::kClamp, {f32, f32, f32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kClamp);
EXPECT_EQ(result->Type(), BuiltinType::kClamp);
EXPECT_EQ(result->ReturnType(), f32);
EXPECT_EQ(result->Parameters()[0]->Type(), f32);
EXPECT_EQ(result->Parameters()[1]->Type(), f32);
EXPECT_EQ(result->Parameters()[2]->Type(), f32);
}
TEST_F(IntrinsicTableTest, MismatchOpenType) {
TEST_F(BuiltinTableTest, MismatchOpenType) {
auto* f32 = create<sem::F32>();
auto* u32 = create<sem::U32>();
auto* result =
table->Lookup(IntrinsicType::kClamp, {f32, u32, f32}, Source{});
auto* result = table->Lookup(BuiltinType::kClamp, {f32, u32, f32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchOpenSizeVector) {
TEST_F(BuiltinTableTest, MatchOpenSizeVector) {
auto* f32 = create<sem::F32>();
auto* vec2_f32 = create<sem::Vector>(f32, 2);
auto* result = table->Lookup(IntrinsicType::kClamp,
auto* result = table->Lookup(BuiltinType::kClamp,
{vec2_f32, vec2_f32, vec2_f32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kClamp);
EXPECT_EQ(result->Type(), BuiltinType::kClamp);
EXPECT_EQ(result->ReturnType(), vec2_f32);
ASSERT_EQ(result->Parameters().size(), 3u);
EXPECT_EQ(result->Parameters()[0]->Type(), vec2_f32);
@ -476,45 +465,44 @@ TEST_F(IntrinsicTableTest, MatchOpenSizeVector) {
EXPECT_EQ(result->Parameters()[2]->Type(), vec2_f32);
}
TEST_F(IntrinsicTableTest, MismatchOpenSizeVector) {
TEST_F(BuiltinTableTest, MismatchOpenSizeVector) {
auto* f32 = create<sem::F32>();
auto* u32 = create<sem::U32>();
auto* vec2_f32 = create<sem::Vector>(f32, 2);
auto* result =
table->Lookup(IntrinsicType::kClamp, {vec2_f32, u32, vec2_f32}, Source{});
table->Lookup(BuiltinType::kClamp, {vec2_f32, u32, vec2_f32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, MatchOpenSizeMatrix) {
TEST_F(BuiltinTableTest, MatchOpenSizeMatrix) {
auto* f32 = create<sem::F32>();
auto* vec3_f32 = create<sem::Vector>(f32, 3);
auto* mat3_f32 = create<sem::Matrix>(vec3_f32, 3);
auto* result =
table->Lookup(IntrinsicType::kDeterminant, {mat3_f32}, Source{});
auto* result = table->Lookup(BuiltinType::kDeterminant, {mat3_f32}, Source{});
ASSERT_NE(result, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
EXPECT_EQ(result->Type(), IntrinsicType::kDeterminant);
EXPECT_EQ(result->Type(), BuiltinType::kDeterminant);
EXPECT_EQ(result->ReturnType(), f32);
ASSERT_EQ(result->Parameters().size(), 1u);
EXPECT_EQ(result->Parameters()[0]->Type(), mat3_f32);
}
TEST_F(IntrinsicTableTest, MismatchOpenSizeMatrix) {
TEST_F(BuiltinTableTest, MismatchOpenSizeMatrix) {
auto* f32 = create<sem::F32>();
auto* vec2_f32 = create<sem::Vector>(f32, 2);
auto* mat3x2_f32 = create<sem::Matrix>(vec2_f32, 3);
auto* result =
table->Lookup(IntrinsicType::kDeterminant, {mat3x2_f32}, Source{});
table->Lookup(BuiltinType::kDeterminant, {mat3x2_f32}, Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
TEST_F(IntrinsicTableTest, OverloadOrderByNumberOfParameters) {
TEST_F(BuiltinTableTest, OverloadOrderByNumberOfParameters) {
// None of the arguments match, so expect the overloads with 2 parameters to
// come first
auto* bool_ = create<sem::Bool>();
table->Lookup(IntrinsicType::kTextureDimensions, {bool_, bool_}, Source{});
table->Lookup(BuiltinType::kTextureDimensions, {bool_, bool_}, Source{});
ASSERT_EQ(Diagnostics().str(),
R"(error: no matching call to textureDimensions(bool, bool)
@ -549,10 +537,10 @@ TEST_F(IntrinsicTableTest, OverloadOrderByNumberOfParameters) {
)");
}
TEST_F(IntrinsicTableTest, OverloadOrderByMatchingParameter) {
TEST_F(BuiltinTableTest, OverloadOrderByMatchingParameter) {
auto* tex = create<sem::DepthTexture>(ast::TextureDimension::k2d);
auto* bool_ = create<sem::Bool>();
table->Lookup(IntrinsicType::kTextureDimensions, {tex, bool_}, Source{});
table->Lookup(BuiltinType::kTextureDimensions, {tex, bool_}, Source{});
ASSERT_EQ(
Diagnostics().str(),
R"(error: no matching call to textureDimensions(texture_depth_2d, bool)
@ -588,18 +576,18 @@ TEST_F(IntrinsicTableTest, OverloadOrderByMatchingParameter) {
)");
}
TEST_F(IntrinsicTableTest, SameOverloadReturnsSameIntrinsicPointer) {
TEST_F(BuiltinTableTest, SameOverloadReturnsSameBuiltinPointer) {
auto* f32 = create<sem::F32>();
auto* vec2_f32 = create<sem::Vector>(create<sem::F32>(), 2);
auto* bool_ = create<sem::Bool>();
auto* a = table->Lookup(IntrinsicType::kSelect, {f32, f32, bool_}, Source{});
auto* a = table->Lookup(BuiltinType::kSelect, {f32, f32, bool_}, Source{});
ASSERT_NE(a, nullptr) << Diagnostics().str();
auto* b = table->Lookup(IntrinsicType::kSelect, {f32, f32, bool_}, Source{});
auto* b = table->Lookup(BuiltinType::kSelect, {f32, f32, bool_}, Source{});
ASSERT_NE(b, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");
auto* c = table->Lookup(IntrinsicType::kSelect, {vec2_f32, vec2_f32, bool_},
auto* c = table->Lookup(BuiltinType::kSelect, {vec2_f32, vec2_f32, bool_},
Source{});
ASSERT_NE(c, nullptr) << Diagnostics().str();
ASSERT_EQ(Diagnostics().str(), "");

View File

@ -13,9 +13,9 @@
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// WGSL intrinsic definition file //
// WGSL builtin definition file //
// //
// This file is used to generate parts of the Tint IntrinsicTable, various //
// This file is used to generate parts of the Tint BuiltinTable, various //
// enum definition files, as well as test .wgsl files. //
////////////////////////////////////////////////////////////////////////////////
@ -134,10 +134,10 @@ match function_private_workgroup: function | private | workgroup
match workgroup_or_storage: workgroup | storage
////////////////////////////////////////////////////////////////////////////////
// Intrinsic Functions //
// Builtin Functions //
// //
// The intrinsic function declarations below declare all the built-in //
// functions supported by the WGSL language. This intrinsic definition //
// The builtin function declarations below declare all the built-in //
// 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'. //
@ -150,7 +150,7 @@ match workgroup_or_storage: workgroup | storage
// 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 intrinsic. //
// arguments to the builtin. //
// //
// * Open-type example without constraint: //
// //
@ -170,7 +170,7 @@ match workgroup_or_storage: workgroup | storage
// same argument type. //
// //
// Similarly an 'open-number' can be thought as a template number or //
// enumerator that is determined by the arguments to the intrinsic. //
// enumerator that is determined by the arguments to the builtin. //
// //
// * Open-number example: //
// //
@ -239,7 +239,7 @@ match workgroup_or_storage: workgroup | storage
// fn F(USAGE : f32) //
// - Single parameter with name USAGE. //
// Note: Parameter names are used by Tint to infer parameter order for //
// some intrinsic functions //
// some builtin functions //
// //
// fn F<T>(T) //
// - Single parameter of unconstrained open-type T (any type) //

View File

@ -785,7 +785,7 @@ void Inspector::GenerateSamplerTargets() {
continue;
}
auto* i = call->Target()->As<sem::Intrinsic>();
auto* i = call->Target()->As<sem::Builtin>();
if (!i) {
continue;
}

View File

@ -1,53 +0,0 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_INTRINSIC_TABLE_H_
#define SRC_INTRINSIC_TABLE_H_
#include <memory>
#include <string>
#include <vector>
#include "src/sem/intrinsic.h"
namespace tint {
// Forward declarations
class ProgramBuilder;
/// IntrinsicTable is a lookup table of all the WGSL intrinsic functions
class IntrinsicTable {
public:
/// @param builder the program builder
/// @return a pointer to a newly created IntrinsicTable
static std::unique_ptr<IntrinsicTable> Create(ProgramBuilder& builder);
/// Destructor
virtual ~IntrinsicTable();
/// Lookup looks for the intrinsic overload with the given signature, raising
/// an error diagnostic if the intrinsic was not found.
/// @param type the intrinsic type
/// @param args the argument types passed to the intrinsic function
/// @param source the source of the intrinsic call
/// @return the semantic intrinsic if found, otherwise nullptr
virtual const sem::Intrinsic* Lookup(
sem::IntrinsicType type,
const std::vector<const sem::Type*>& args,
const Source& source) = 0;
};
} // namespace tint
#endif // SRC_INTRINSIC_TABLE_H_

View File

@ -33,8 +33,8 @@
#include "src/ast/switch_statement.h"
#include "src/ast/unary_op_expression.h"
#include "src/ast/variable_decl_statement.h"
#include "src/sem/builtin_type.h"
#include "src/sem/depth_texture_type.h"
#include "src/sem/intrinsic_type.h"
#include "src/sem/sampled_texture_type.h"
// Terms:
@ -437,38 +437,38 @@ std::string GetGlslStd450FuncName(uint32_t ext_opcode) {
return "";
}
// Returns the WGSL standard library function intrinsic for the
// given instruction, or sem::IntrinsicType::kNone
sem::IntrinsicType GetIntrinsic(SpvOp opcode) {
// Returns the WGSL standard library function builtin for the
// given instruction, or sem::BuiltinType::kNone
sem::BuiltinType GetBuiltin(SpvOp opcode) {
switch (opcode) {
case SpvOpBitCount:
return sem::IntrinsicType::kCountOneBits;
return sem::BuiltinType::kCountOneBits;
case SpvOpBitReverse:
return sem::IntrinsicType::kReverseBits;
return sem::BuiltinType::kReverseBits;
case SpvOpDot:
return sem::IntrinsicType::kDot;
return sem::BuiltinType::kDot;
case SpvOpDPdx:
return sem::IntrinsicType::kDpdx;
return sem::BuiltinType::kDpdx;
case SpvOpDPdy:
return sem::IntrinsicType::kDpdy;
return sem::BuiltinType::kDpdy;
case SpvOpFwidth:
return sem::IntrinsicType::kFwidth;
return sem::BuiltinType::kFwidth;
case SpvOpDPdxFine:
return sem::IntrinsicType::kDpdxFine;
return sem::BuiltinType::kDpdxFine;
case SpvOpDPdyFine:
return sem::IntrinsicType::kDpdyFine;
return sem::BuiltinType::kDpdyFine;
case SpvOpFwidthFine:
return sem::IntrinsicType::kFwidthFine;
return sem::BuiltinType::kFwidthFine;
case SpvOpDPdxCoarse:
return sem::IntrinsicType::kDpdxCoarse;
return sem::BuiltinType::kDpdxCoarse;
case SpvOpDPdyCoarse:
return sem::IntrinsicType::kDpdyCoarse;
return sem::BuiltinType::kDpdyCoarse;
case SpvOpFwidthCoarse:
return sem::IntrinsicType::kFwidthCoarse;
return sem::BuiltinType::kFwidthCoarse;
default:
break;
}
return sem::IntrinsicType::kNone;
return sem::BuiltinType::kNone;
}
// @param opcode a SPIR-V opcode
@ -3888,9 +3888,9 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
std::move(params))};
}
const auto intrinsic = GetIntrinsic(opcode);
if (intrinsic != sem::IntrinsicType::kNone) {
return MakeIntrinsicCall(inst);
const auto builtin = GetBuiltin(opcode);
if (builtin != sem::BuiltinType::kNone) {
return MakeBuiltinCall(inst);
}
if (opcode == SpvOpFMod) {
@ -5081,10 +5081,10 @@ bool FunctionEmitter::EmitControlBarrier(
return true;
}
TypedExpression FunctionEmitter::MakeIntrinsicCall(
TypedExpression FunctionEmitter::MakeBuiltinCall(
const spvtools::opt::Instruction& inst) {
const auto intrinsic = GetIntrinsic(inst.opcode());
auto* name = sem::str(intrinsic);
const auto builtin = GetBuiltin(inst.opcode());
auto* name = sem::str(builtin);
auto* ident = create<ast::IdentifierExpression>(
Source{}, builder_.Symbols().Register(name));
@ -5864,7 +5864,7 @@ TypedExpression FunctionEmitter::MakeArrayLength(
auto* member_access = create<ast::MemberAccessorExpression>(
Source{}, member_expr.expr, member_ident);
// Generate the intrinsic function call.
// Generate the builtin function call.
auto* call_expr =
builder_.Call(Source{}, "arrayLength", builder_.AddressOf(member_access));

View File

@ -995,17 +995,17 @@ class FunctionEmitter {
/// @returns false if emission failed
bool EmitFunctionCall(const spvtools::opt::Instruction& inst);
/// Emits a control barrier intrinsic. On failure, emits a diagnostic and
/// Emits a control barrier builtin. On failure, emits a diagnostic and
/// returns false.
/// @param inst the SPIR-V control barrier instruction
/// @returns false if emission failed
bool EmitControlBarrier(const spvtools::opt::Instruction& inst);
/// Returns an expression for a SPIR-V instruction that maps to a WGSL
/// intrinsic function call.
/// builtin function call.
/// @param inst the SPIR-V instruction
/// @returns an expression
TypedExpression MakeIntrinsicCall(const spvtools::opt::Instruction& inst);
TypedExpression MakeBuiltinCall(const spvtools::opt::Instruction& inst);
/// Returns an expression for a SPIR-V OpArrayLength instruction.
/// @param inst the SPIR-V instruction

View File

@ -935,11 +935,11 @@ TEST_F(SpvBinaryArithTestBasic, OuterProduct) {
<< got;
}
struct IntrinsicData {
struct BuiltinData {
const std::string spirv;
const std::string wgsl;
};
inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
out << "OpData{" << data.spirv << "," << data.wgsl << "}";
return out;
}
@ -955,10 +955,10 @@ inline std::ostream& operator<<(std::ostream& out, ArgAndTypeData data) {
}
using SpvBinaryDerivativeTest = SpvParserTestBase<
::testing::TestWithParam<std::tuple<IntrinsicData, ArgAndTypeData>>>;
::testing::TestWithParam<std::tuple<BuiltinData, ArgAndTypeData>>>;
TEST_P(SpvBinaryDerivativeTest, Derivatives) {
auto& intrinsic = std::get<0>(GetParam());
auto& builtin = std::get<0>(GetParam());
auto& arg = std::get<1>(GetParam());
const auto assembly = R"(
@ -968,7 +968,7 @@ TEST_P(SpvBinaryDerivativeTest, Derivatives) {
%entry = OpLabel
%1 = OpCopyObject %)" +
arg.spirv_type + " %" + arg.spirv_arg + R"(
%2 = )" + intrinsic.spirv +
%2 = )" + builtin.spirv +
" %" + arg.spirv_type + R"( %1
OpReturn
OpFunctionEnd
@ -979,24 +979,24 @@ TEST_P(SpvBinaryDerivativeTest, Derivatives) {
auto fe = p->function_emitter(100);
EXPECT_TRUE(fe.EmitBody()) << p->error();
auto ast_body = fe.ast_body();
EXPECT_THAT(test::ToString(p->program(), ast_body),
HasSubstr("let x_2 : " + arg.ast_type + " = " + intrinsic.wgsl +
"(x_1);"));
EXPECT_THAT(
test::ToString(p->program(), ast_body),
HasSubstr("let x_2 : " + arg.ast_type + " = " + builtin.wgsl + "(x_1);"));
}
INSTANTIATE_TEST_SUITE_P(
SpvBinaryDerivativeTest,
SpvBinaryDerivativeTest,
testing::Combine(
::testing::Values(IntrinsicData{"OpDPdx", "dpdx"},
IntrinsicData{"OpDPdy", "dpdy"},
IntrinsicData{"OpFwidth", "fwidth"},
IntrinsicData{"OpDPdxFine", "dpdxFine"},
IntrinsicData{"OpDPdyFine", "dpdyFine"},
IntrinsicData{"OpFwidthFine", "fwidthFine"},
IntrinsicData{"OpDPdxCoarse", "dpdxCoarse"},
IntrinsicData{"OpDPdyCoarse", "dpdyCoarse"},
IntrinsicData{"OpFwidthCoarse", "fwidthCoarse"}),
::testing::Values(BuiltinData{"OpDPdx", "dpdx"},
BuiltinData{"OpDPdy", "dpdy"},
BuiltinData{"OpFwidth", "fwidth"},
BuiltinData{"OpDPdxFine", "dpdxFine"},
BuiltinData{"OpDPdyFine", "dpdyFine"},
BuiltinData{"OpFwidthFine", "fwidthFine"},
BuiltinData{"OpDPdxCoarse", "dpdxCoarse"},
BuiltinData{"OpDPdyCoarse", "dpdyCoarse"},
BuiltinData{"OpFwidthCoarse", "fwidthCoarse"}),
::testing::Values(
ArgAndTypeData{"float", "float_50", "f32"},
ArgAndTypeData{"v2float", "v2float_50_60", "vec2<f32>"},

View File

@ -74,9 +74,9 @@ TEST_F(SpvParserTest, WorkgroupBarrier) {
EXPECT_EQ(call->expr->args.size(), 0u);
auto* sem_call = program.Sem().Get(call->expr);
ASSERT_NE(sem_call, nullptr);
auto* intrinsic = sem_call->Target()->As<sem::Intrinsic>();
ASSERT_NE(intrinsic, nullptr);
EXPECT_EQ(intrinsic->Type(), sem::IntrinsicType::kWorkgroupBarrier);
auto* builtin = sem_call->Target()->As<sem::Builtin>();
ASSERT_NE(builtin, nullptr);
EXPECT_EQ(builtin->Type(), sem::BuiltinType::kWorkgroupBarrier);
}
TEST_F(SpvParserTest, StorageBarrier) {
@ -108,9 +108,9 @@ TEST_F(SpvParserTest, StorageBarrier) {
EXPECT_EQ(call->expr->args.size(), 0u);
auto* sem_call = program.Sem().Get(call->expr);
ASSERT_NE(sem_call, nullptr);
auto* intrinsic = sem_call->Target()->As<sem::Intrinsic>();
ASSERT_NE(intrinsic, nullptr);
EXPECT_EQ(intrinsic->Type(), sem::IntrinsicType::kStorageBarrier);
auto* builtin = sem_call->Target()->As<sem::Builtin>();
ASSERT_NE(builtin, nullptr);
EXPECT_EQ(builtin->Type(), sem::BuiltinType::kStorageBarrier);
}
TEST_F(SpvParserTest, ErrBarrierInvalidExecution) {

View File

@ -114,7 +114,7 @@ fn f() { a = 1 }
)");
}
TEST_F(ParserImplErrorTest, AssignmentStmtInvalidLHS_IntrinsicFunctionName) {
TEST_F(ParserImplErrorTest, AssignmentStmtInvalidLHS_BuiltinFunctionName) {
EXPECT("normalize = 5;",
R"(test.wgsl:1:1 error: statement found outside of function body
normalize = 5;

View File

@ -12,16 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/intrinsic_texture_helper_test.h"
#include "src/ast/builtin_texture_helper_test.h"
#include "src/resolver/resolver_test_helper.h"
namespace tint {
namespace resolver {
namespace {
using ResolverIntrinsicValidationTest = ResolverTest;
using ResolverBuiltinValidationTest = ResolverTest;
TEST_F(ResolverIntrinsicValidationTest,
TEST_F(ResolverBuiltinValidationTest,
FunctionTypeMustMatchReturnStatementType_void_fail) {
// fn func { return workgroupBarrier(); }
Func("func", {}, ty.void_(),
@ -30,12 +30,11 @@ TEST_F(ResolverIntrinsicValidationTest,
});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
"12:34 error: intrinsic 'workgroupBarrier' does not return a value");
EXPECT_EQ(r()->error(),
"12:34 error: builtin 'workgroupBarrier' does not return a value");
}
TEST_F(ResolverIntrinsicValidationTest, InvalidPipelineStageDirect) {
TEST_F(ResolverBuiltinValidationTest, InvalidPipelineStageDirect) {
// @stage(compute) @workgroup_size(1) fn func { return dpdx(1.0); }
auto* dpdx = create<ast::CallExpression>(Source{{3, 4}}, Expr("dpdx"),
@ -49,7 +48,7 @@ TEST_F(ResolverIntrinsicValidationTest, InvalidPipelineStageDirect) {
"3:4 error: built-in cannot be used by compute pipeline stage");
}
TEST_F(ResolverIntrinsicValidationTest, InvalidPipelineStageIndirect) {
TEST_F(ResolverBuiltinValidationTest, InvalidPipelineStageIndirect) {
// fn f0 { return dpdx(1.0); }
// fn f1 { f0(); }
// fn f2 { f1(); }
@ -75,7 +74,7 @@ TEST_F(ResolverIntrinsicValidationTest, InvalidPipelineStageIndirect) {
7:8 note: called by entry point 'main')");
}
TEST_F(ResolverIntrinsicValidationTest, IntrinsicRedeclaredAsFunction) {
TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsFunction) {
Func(Source{{12, 34}}, "mix", {}, ty.i32(), {});
EXPECT_FALSE(r()->Resolve());
@ -84,7 +83,7 @@ TEST_F(ResolverIntrinsicValidationTest, IntrinsicRedeclaredAsFunction) {
R"(12:34 error: 'mix' is a builtin and cannot be redeclared as a function)");
}
TEST_F(ResolverIntrinsicValidationTest, IntrinsicRedeclaredAsGlobalLet) {
TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalLet) {
GlobalConst(Source{{12, 34}}, "mix", ty.i32(), Expr(1));
EXPECT_FALSE(r()->Resolve());
@ -93,7 +92,7 @@ TEST_F(ResolverIntrinsicValidationTest, IntrinsicRedeclaredAsGlobalLet) {
R"(12:34 error: 'mix' is a builtin and cannot be redeclared as a module-scope let)");
}
TEST_F(ResolverIntrinsicValidationTest, IntrinsicRedeclaredAsGlobalVar) {
TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalVar) {
Global(Source{{12, 34}}, "mix", ty.i32(), Expr(1),
ast::StorageClass::kPrivate);
@ -103,7 +102,7 @@ TEST_F(ResolverIntrinsicValidationTest, IntrinsicRedeclaredAsGlobalVar) {
R"(12:34 error: 'mix' is a builtin and cannot be redeclared as a module-scope var)");
}
TEST_F(ResolverIntrinsicValidationTest, IntrinsicRedeclaredAsAlias) {
TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsAlias) {
Alias(Source{{12, 34}}, "mix", ty.i32());
EXPECT_FALSE(r()->Resolve());
@ -112,7 +111,7 @@ TEST_F(ResolverIntrinsicValidationTest, IntrinsicRedeclaredAsAlias) {
R"(12:34 error: 'mix' is a builtin and cannot be redeclared as an alias)");
}
TEST_F(ResolverIntrinsicValidationTest, IntrinsicRedeclaredAsStruct) {
TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsStruct) {
Structure(Source{{12, 34}}, "mix", {Member("m", ty.i32())});
EXPECT_FALSE(r()->Resolve());
@ -123,10 +122,10 @@ TEST_F(ResolverIntrinsicValidationTest, IntrinsicRedeclaredAsStruct) {
namespace texture_constexpr_args {
using TextureOverloadCase = ast::intrinsic::test::TextureOverloadCase;
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
using TextureKind = ast::intrinsic::test::TextureKind;
using TextureDataType = ast::intrinsic::test::TextureDataType;
using TextureOverloadCase = ast::builtin::test::TextureOverloadCase;
using ValidTextureOverload = ast::builtin::test::ValidTextureOverload;
using TextureKind = ast::builtin::test::TextureKind;
using TextureDataType = ast::builtin::test::TextureDataType;
using u32 = ProgramBuilder::u32;
using i32 = ProgramBuilder::i32;
using f32 = ProgramBuilder::f32;
@ -229,10 +228,10 @@ static std::ostream& operator<<(std::ostream& out, Constexpr expr) {
return out;
}
using IntrinsicTextureConstExprArgValidationTest = ResolverTestWithParam<
using BuiltinTextureConstExprArgValidationTest = ResolverTestWithParam<
std::tuple<TextureOverloadCase, Parameter, Constexpr>>;
TEST_P(IntrinsicTextureConstExprArgValidationTest, Immediate) {
TEST_P(BuiltinTextureConstExprArgValidationTest, Immediate) {
auto& p = GetParam();
auto overload = std::get<0>(p);
auto param = std::get<1>(p);
@ -255,7 +254,7 @@ TEST_P(IntrinsicTextureConstExprArgValidationTest, Immediate) {
arg_to_replace = expr(Source{{12, 34}}, *this);
// Call the intrinsic with the constexpr argument replaced
// Call the builtin with the constexpr argument replaced
Func("func", {}, ty.void_(), {CallStmt(Call(overload.function, args))},
{Stage(ast::PipelineStage::kFragment)});
@ -279,7 +278,7 @@ TEST_P(IntrinsicTextureConstExprArgValidationTest, Immediate) {
}
}
TEST_P(IntrinsicTextureConstExprArgValidationTest, GlobalConst) {
TEST_P(BuiltinTextureConstExprArgValidationTest, GlobalConst) {
auto& p = GetParam();
auto overload = std::get<0>(p);
auto param = std::get<1>(p);
@ -302,7 +301,7 @@ TEST_P(IntrinsicTextureConstExprArgValidationTest, GlobalConst) {
arg_to_replace = Expr(Source{{12, 34}}, "G");
// Call the intrinsic with the constexpr argument replaced
// Call the builtin with the constexpr argument replaced
Func("func", {}, ty.void_(), {CallStmt(Call(overload.function, args))},
{Stage(ast::PipelineStage::kFragment)});
@ -315,7 +314,7 @@ TEST_P(IntrinsicTextureConstExprArgValidationTest, GlobalConst) {
INSTANTIATE_TEST_SUITE_P(
Offset2D,
IntrinsicTextureConstExprArgValidationTest,
BuiltinTextureConstExprArgValidationTest,
testing::Combine(
testing::ValuesIn(TextureCases({
ValidTextureOverload::kSample2dOffsetF32,
@ -349,7 +348,7 @@ INSTANTIATE_TEST_SUITE_P(
INSTANTIATE_TEST_SUITE_P(
Offset3D,
IntrinsicTextureConstExprArgValidationTest,
BuiltinTextureConstExprArgValidationTest,
testing::Combine(
testing::ValuesIn(TextureCases({
ValidTextureOverload::kSample3dOffsetF32,
@ -377,7 +376,7 @@ INSTANTIATE_TEST_SUITE_P(
INSTANTIATE_TEST_SUITE_P(
Component,
IntrinsicTextureConstExprArgValidationTest,
BuiltinTextureConstExprArgValidationTest,
testing::Combine(
testing::ValuesIn(
TextureCases({ValidTextureOverload::kGather2dF32,

View File

@ -24,7 +24,7 @@
#include "src/ast/fallthrough_statement.h"
#include "src/ast/traverse_expressions.h"
#include "src/scope_stack.h"
#include "src/sem/intrinsic.h"
#include "src/sem/builtin.h"
#include "src/utils/defer.h"
#include "src/utils/map.h"
#include "src/utils/scoped_assignment.h"
@ -297,7 +297,7 @@ class DependencyScanner {
if (auto* ident = expr->As<ast::IdentifierExpression>()) {
auto* node = scope_stack_.Get(ident->symbol);
if (node == nullptr) {
if (!IsIntrinsic(ident->symbol)) {
if (!IsBuiltin(ident->symbol)) {
UnknownSymbol(ident->symbol, ident->source, "identifier");
}
return ast::TraverseAction::Descend;
@ -313,7 +313,7 @@ class DependencyScanner {
}
if (auto* call = expr->As<ast::CallExpression>()) {
if (call->target.name) {
if (!IsIntrinsic(call->target.name->symbol)) {
if (!IsBuiltin(call->target.name->symbol)) {
AddGlobalDependency(call->target.name,
call->target.name->symbol, "function",
"calls");
@ -436,10 +436,10 @@ class DependencyScanner {
}
}
/// @returns true if `name` is the name of an intrinsic function
bool IsIntrinsic(Symbol name) const {
return sem::ParseIntrinsicType(symbols_.NameFor(name)) !=
sem::IntrinsicType::kNone;
/// @returns true if `name` is the name of a builtin function
bool IsBuiltin(Symbol name) const {
return sem::ParseBuiltinType(symbols_.NameFor(name)) !=
sem::BuiltinType::kNone;
}
/// Appends an error to the diagnostics that the given symbol cannot be

View File

@ -84,7 +84,7 @@ namespace resolver {
Resolver::Resolver(ProgramBuilder* builder)
: builder_(builder),
diagnostics_(builder->Diagnostics()),
intrinsic_table_(IntrinsicTable::Create(*builder)) {}
builtin_table_(BuiltinTable::Create(*builder)) {}
Resolver::~Resolver() = default;
@ -1354,10 +1354,9 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
}
auto name = builder_->Symbols().NameFor(ident->symbol);
auto intrinsic_type = sem::ParseIntrinsicType(name);
if (intrinsic_type != sem::IntrinsicType::kNone) {
return IntrinsicCall(expr, intrinsic_type, std::move(args),
std::move(arg_tys));
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_)
@ -1368,36 +1367,35 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
return nullptr;
}
sem::Call* Resolver::IntrinsicCall(
const ast::CallExpression* expr,
sem::IntrinsicType intrinsic_type,
const std::vector<const sem::Expression*> args,
const std::vector<const sem::Type*> arg_tys) {
auto* intrinsic = intrinsic_table_->Lookup(intrinsic_type, std::move(arg_tys),
expr->source);
if (!intrinsic) {
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 =
builtin_table_->Lookup(builtin_type, std::move(arg_tys), expr->source);
if (!builtin) {
return nullptr;
}
if (intrinsic->IsDeprecated()) {
AddWarning("use of deprecated intrinsic", expr->source);
if (builtin->IsDeprecated()) {
AddWarning("use of deprecated builtin", expr->source);
}
auto* call = builder_->create<sem::Call>(expr, intrinsic, std::move(args),
auto* call = builder_->create<sem::Call>(expr, builtin, std::move(args),
current_statement_, sem::Constant{});
current_function_->AddDirectlyCalledIntrinsic(intrinsic);
current_function_->AddDirectlyCalledBuiltin(builtin);
if (IsTextureIntrinsic(intrinsic_type)) {
if (!ValidateTextureIntrinsicFunction(call)) {
if (IsTextureBuiltin(builtin_type)) {
if (!ValidateTextureBuiltinFunction(call)) {
return nullptr;
}
// Collect a texture/sampler pair for this intrinsic.
const auto& signature = intrinsic->Signature();
// 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 intrinsic without texture parameter";
<< "texture builtin without texture parameter";
}
auto* texture = args[texture_index]->As<sem::VariableUser>()->Variable();
@ -1409,7 +1407,7 @@ sem::Call* Resolver::IntrinsicCall(
current_function_->AddTextureSamplerPair(texture, sampler);
}
if (!ValidateIntrinsicCall(call)) {
if (!ValidateBuiltinCall(call)) {
return nullptr;
}
@ -1662,8 +1660,8 @@ sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
return nullptr;
}
if (IsIntrinsic(symbol)) {
AddError("missing '(' for intrinsic call", expr->source.End());
if (IsBuiltin(symbol)) {
AddError("missing '(' for builtin call", expr->source.End());
return nullptr;
}
@ -2786,9 +2784,9 @@ bool Resolver::IsHostShareable(const sem::Type* type) const {
return false;
}
bool Resolver::IsIntrinsic(Symbol symbol) const {
bool Resolver::IsBuiltin(Symbol symbol) const {
std::string name = builder_->Symbols().NameFor(symbol);
return sem::ParseIntrinsicType(name) != sem::IntrinsicType::kNone;
return sem::ParseBuiltinType(name) != sem::BuiltinType::kNone;
}
bool Resolver::IsCallStatement(const ast::Expression* expr) const {

View File

@ -23,7 +23,7 @@
#include <utility>
#include <vector>
#include "src/intrinsic_table.h"
#include "src/builtin_table.h"
#include "src/program_builder.h"
#include "src/resolver/dependency_graph.h"
#include "src/scope_stack.h"
@ -59,11 +59,11 @@ namespace sem {
class Array;
class Atomic;
class BlockStatement;
class Builtin;
class CaseStatement;
class ElseStatement;
class ForLoopStatement;
class IfStatement;
class Intrinsic;
class LoopStatement;
class Statement;
class SwitchStatement;
@ -191,10 +191,10 @@ class Resolver {
const std::vector<const sem::Expression*> args,
sem::Behaviors arg_behaviors);
sem::Expression* Identifier(const ast::IdentifierExpression*);
sem::Call* IntrinsicCall(const ast::CallExpression*,
sem::IntrinsicType,
const std::vector<const sem::Expression*> args,
const std::vector<const sem::Type*> arg_tys);
sem::Call* BuiltinCall(const ast::CallExpression*,
sem::BuiltinType,
const std::vector<const sem::Expression*> args,
const std::vector<const sem::Type*> arg_tys);
sem::Expression* Literal(const ast::LiteralExpression*);
sem::Expression* MemberAccessor(const ast::MemberAccessorExpression*);
sem::Call* TypeConversion(const ast::CallExpression* expr,
@ -258,7 +258,7 @@ class Resolver {
bool ValidateIfStatement(const sem::IfStatement* stmt);
bool ValidateInterpolateAttribute(const ast::InterpolateAttribute* attr,
const sem::Type* storage_type);
bool ValidateIntrinsicCall(const sem::Call* call);
bool ValidateBuiltinCall(const sem::Call* call);
bool ValidateLocationAttribute(const ast::LocationAttribute* location,
const sem::Type* type,
std::unordered_set<uint32_t>& locations,
@ -290,7 +290,7 @@ class Resolver {
const sem::Type* type);
bool ValidateArrayConstructorOrCast(const ast::CallExpression* ctor,
const sem::Array* arr_type);
bool ValidateTextureIntrinsicFunction(const sem::Call* call);
bool ValidateTextureBuiltinFunction(const sem::Call* call);
bool ValidateNoDuplicateAttributes(const ast::AttributeList& attributes);
bool ValidateStorageClassLayout(const sem::Type* type,
ast::StorageClass sc,
@ -462,9 +462,8 @@ class Resolver {
return const_cast<T*>(As<T>(sem));
}
/// @returns true if the symbol is the name of an intrinsic (builtin)
/// function.
bool IsIntrinsic(Symbol) const;
/// @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;
@ -520,7 +519,7 @@ class Resolver {
ProgramBuilder* const builder_;
diag::List& diagnostics_;
std::unique_ptr<IntrinsicTable> const intrinsic_table_;
std::unique_ptr<BuiltinTable> const builtin_table_;
DependencyGraph dependencies_;
std::vector<sem::Function*> entry_points_;
std::unordered_map<const sem::Type*, const Source&> atomic_composite_info_;

View File

@ -21,11 +21,11 @@
#include "src/ast/assignment_statement.h"
#include "src/ast/bitcast_expression.h"
#include "src/ast/break_statement.h"
#include "src/ast/builtin_texture_helper_test.h"
#include "src/ast/call_statement.h"
#include "src/ast/continue_statement.h"
#include "src/ast/float_literal_expression.h"
#include "src/ast/if_statement.h"
#include "src/ast/intrinsic_texture_helper_test.h"
#include "src/ast/loop_statement.h"
#include "src/ast/override_attribute.h"
#include "src/ast/return_statement.h"
@ -535,7 +535,7 @@ TEST_F(ResolverTest, Expr_Call_WithParams) {
EXPECT_TRUE(TypeOf(param)->Is<sem::F32>());
}
TEST_F(ResolverTest, Expr_Call_Intrinsic) {
TEST_F(ResolverTest, Expr_Call_Builtin) {
auto* call = Call("round", 2.4f);
WrapInFunction(call);

View File

@ -560,7 +560,7 @@ bool Resolver::ValidateVariable(const sem::Variable* var) {
if (var->Is<sem::GlobalVariable>()) {
auto name = builder_->Symbols().NameFor(decl->symbol);
if (sem::ParseIntrinsicType(name) != sem::IntrinsicType::kNone) {
if (sem::ParseBuiltinType(name) != sem::BuiltinType::kNone) {
auto* kind = var->Declaration()->is_const ? "let" : "var";
AddError(
"'" + name +
@ -840,7 +840,7 @@ bool Resolver::ValidateFunction(const sem::Function* func) {
auto* decl = func->Declaration();
auto name = builder_->Symbols().NameFor(decl->symbol);
if (sem::ParseIntrinsicType(name) != sem::IntrinsicType::kNone) {
if (sem::ParseBuiltinType(name) != sem::BuiltinType::kNone) {
AddError(
"'" + name + "' is a builtin and cannot be redeclared as a function",
decl->source);
@ -1369,7 +1369,7 @@ bool Resolver::ValidateIfStatement(const sem::IfStatement* stmt) {
return true;
}
bool Resolver::ValidateIntrinsicCall(const sem::Call* call) {
bool Resolver::ValidateBuiltinCall(const sem::Call* call) {
if (call->Type()->Is<sem::Void>()) {
bool is_call_statement = false;
if (auto* call_stmt = As<ast::CallStatement>(call->Stmt()->Declaration())) {
@ -1383,7 +1383,7 @@ bool Resolver::ValidateIntrinsicCall(const sem::Call* call) {
// statement should be used instead.
auto* ident = call->Declaration()->target.name;
auto name = builder_->Symbols().NameFor(ident->symbol);
AddError("intrinsic '" + name + "' does not return a value",
AddError("builtin '" + name + "' does not return a value",
call->Declaration()->source);
return false;
}
@ -1392,14 +1392,14 @@ bool Resolver::ValidateIntrinsicCall(const sem::Call* call) {
return true;
}
bool Resolver::ValidateTextureIntrinsicFunction(const sem::Call* call) {
auto* intrinsic = call->Target()->As<sem::Intrinsic>();
if (!intrinsic) {
bool Resolver::ValidateTextureBuiltinFunction(const sem::Call* call) {
auto* builtin = call->Target()->As<sem::Builtin>();
if (!builtin) {
return false;
}
std::string func_name = intrinsic->str();
auto& signature = intrinsic->Signature();
std::string func_name = builtin->str();
auto& signature = builtin->Signature();
auto check_arg_is_constexpr = [&](sem::ParameterUsage usage, int min,
int max) {
@ -1431,7 +1431,7 @@ bool Resolver::ValidateTextureIntrinsicFunction(const sem::Call* call) {
return ast::TraverseAction::Stop;
});
if (is_const_expr) {
auto vector = intrinsic->Parameters()[index]->Type()->Is<sem::Vector>();
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;
if (value < min || value > max) {
@ -1895,12 +1895,12 @@ bool Resolver::ValidatePipelineStages() {
}
}
auto check_intrinsic_calls = [&](const sem::Function* func,
const sem::Function* entry_point) {
auto check_builtin_calls = [&](const sem::Function* func,
const sem::Function* entry_point) {
auto stage = entry_point->Declaration()->PipelineStage();
for (auto* intrinsic : func->DirectlyCalledIntrinsics()) {
if (!intrinsic->SupportedStages().Contains(stage)) {
auto* call = func->FindDirectCallTo(intrinsic);
for (auto* builtin : func->DirectlyCalledBuiltins()) {
if (!builtin->SupportedStages().Contains(stage)) {
auto* call = func->FindDirectCallTo(builtin);
std::stringstream err;
err << "built-in cannot be used by " << stage << " pipeline stage";
AddError(err.str(), call ? call->Declaration()->source
@ -1927,11 +1927,11 @@ bool Resolver::ValidatePipelineStages() {
};
for (auto* entry_point : entry_points_) {
if (!check_intrinsic_calls(entry_point, entry_point)) {
if (!check_builtin_calls(entry_point, entry_point)) {
return false;
}
for (auto* func : entry_point->TransitivelyCalledFunctions()) {
if (!check_intrinsic_calls(func, entry_point)) {
if (!check_builtin_calls(func, entry_point)) {
return false;
}
}
@ -1974,7 +1974,7 @@ bool Resolver::ValidateArrayStrideAttribute(const ast::StrideAttribute* attr,
bool Resolver::ValidateAlias(const ast::Alias* alias) {
auto name = builder_->Symbols().NameFor(alias->name);
if (sem::ParseIntrinsicType(name) != sem::IntrinsicType::kNone) {
if (sem::ParseBuiltinType(name) != sem::BuiltinType::kNone) {
AddError("'" + name + "' is a builtin and cannot be redeclared as an alias",
alias->source);
return false;
@ -1985,7 +1985,7 @@ bool Resolver::ValidateAlias(const ast::Alias* alias) {
bool Resolver::ValidateStructure(const sem::Struct* str) {
auto name = builder_->Symbols().NameFor(str->Declaration()->name);
if (sem::ParseIntrinsicType(name) != sem::IntrinsicType::kNone) {
if (sem::ParseBuiltinType(name) != sem::BuiltinType::kNone) {
AddError("'" + name + "' is a builtin and cannot be redeclared as a struct",
str->Declaration()->source);
return false;

View File

@ -19,11 +19,11 @@
#include "src/ast/assignment_statement.h"
#include "src/ast/bitcast_expression.h"
#include "src/ast/break_statement.h"
#include "src/ast/builtin_texture_helper_test.h"
#include "src/ast/call_statement.h"
#include "src/ast/continue_statement.h"
#include "src/ast/discard_statement.h"
#include "src/ast/if_statement.h"
#include "src/ast/intrinsic_texture_helper_test.h"
#include "src/ast/loop_statement.h"
#include "src/ast/return_statement.h"
#include "src/ast/stage_attribute.h"
@ -156,11 +156,11 @@ TEST_F(ResolverValidationTest, Expr_DontCall_Function) {
EXPECT_EQ(r()->error(), "3:8 error: missing '(' for function call");
}
TEST_F(ResolverValidationTest, Expr_DontCall_Intrinsic) {
TEST_F(ResolverValidationTest, Expr_DontCall_Builtin) {
WrapInFunction(Expr(Source{{{3, 3}, {3, 8}}}, "round"));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "3:8 error: missing '(' for intrinsic call");
EXPECT_EQ(r()->error(), "3:8 error: missing '(' for builtin call");
}
TEST_F(ResolverValidationTest, Expr_DontCall_Type) {
@ -172,8 +172,7 @@ TEST_F(ResolverValidationTest, Expr_DontCall_Type) {
"3:8 error: missing '(' for type constructor or cast");
}
TEST_F(ResolverValidationTest,
AssignmentStmt_InvalidLHS_IntrinsicFunctionName) {
TEST_F(ResolverValidationTest, AssignmentStmt_InvalidLHS_BuiltinFunctionName) {
// normalize = 2;
auto* lhs = Expr(Source{{12, 34}}, "normalize");
@ -182,7 +181,7 @@ TEST_F(ResolverValidationTest,
WrapInFunction(assign);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: missing '(' for intrinsic call");
EXPECT_EQ(r()->error(), "12:34 error: missing '(' for builtin call");
}
TEST_F(ResolverValidationTest, UsingUndefinedVariable_Fail) {

166
src/sem/builtin.cc Normal file
View File

@ -0,0 +1,166 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Doxygen seems to trip over this file for some unknown reason. Disable.
//! @cond Doxygen_Suppress
#include "src/sem/builtin.h"
#include <vector>
#include "src/utils/to_const_ptr_vec.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Builtin);
namespace tint {
namespace sem {
const char* Builtin::str() const {
return sem::str(type_);
}
bool IsCoarseDerivativeBuiltin(BuiltinType i) {
return i == BuiltinType::kDpdxCoarse || i == BuiltinType::kDpdyCoarse ||
i == BuiltinType::kFwidthCoarse;
}
bool IsFineDerivativeBuiltin(BuiltinType i) {
return i == BuiltinType::kDpdxFine || i == BuiltinType::kDpdyFine ||
i == BuiltinType::kFwidthFine;
}
bool IsDerivativeBuiltin(BuiltinType i) {
return i == BuiltinType::kDpdx || i == BuiltinType::kDpdy ||
i == BuiltinType::kFwidth || IsCoarseDerivativeBuiltin(i) ||
IsFineDerivativeBuiltin(i);
}
bool IsFloatClassificationBuiltin(BuiltinType i) {
return i == BuiltinType::kIsFinite || i == BuiltinType::kIsInf ||
i == BuiltinType::kIsNan || i == BuiltinType::kIsNormal;
}
bool IsTextureBuiltin(BuiltinType i) {
return IsImageQueryBuiltin(i) || i == BuiltinType::kTextureLoad ||
i == BuiltinType::kTextureGather ||
i == BuiltinType::kTextureGatherCompare ||
i == BuiltinType::kTextureSample ||
i == BuiltinType::kTextureSampleLevel ||
i == BuiltinType::kTextureSampleBias ||
i == BuiltinType::kTextureSampleCompare ||
i == BuiltinType::kTextureSampleCompareLevel ||
i == BuiltinType::kTextureSampleGrad ||
i == BuiltinType::kTextureStore;
}
bool IsImageQueryBuiltin(BuiltinType i) {
return i == BuiltinType::kTextureDimensions ||
i == BuiltinType::kTextureNumLayers ||
i == BuiltinType::kTextureNumLevels ||
i == BuiltinType::kTextureNumSamples;
}
bool IsDataPackingBuiltin(BuiltinType i) {
return i == BuiltinType::kPack4x8snorm || i == BuiltinType::kPack4x8unorm ||
i == BuiltinType::kPack2x16snorm || i == BuiltinType::kPack2x16unorm ||
i == BuiltinType::kPack2x16float;
}
bool IsDataUnpackingBuiltin(BuiltinType i) {
return i == BuiltinType::kUnpack4x8snorm ||
i == BuiltinType::kUnpack4x8unorm ||
i == BuiltinType::kUnpack2x16snorm ||
i == BuiltinType::kUnpack2x16unorm ||
i == BuiltinType::kUnpack2x16float;
}
bool IsBarrierBuiltin(BuiltinType i) {
return i == BuiltinType::kWorkgroupBarrier ||
i == BuiltinType::kStorageBarrier;
}
bool IsAtomicBuiltin(BuiltinType i) {
return i == sem::BuiltinType::kAtomicLoad ||
i == sem::BuiltinType::kAtomicStore ||
i == sem::BuiltinType::kAtomicAdd ||
i == sem::BuiltinType::kAtomicSub ||
i == sem::BuiltinType::kAtomicMax ||
i == sem::BuiltinType::kAtomicMin ||
i == sem::BuiltinType::kAtomicAnd ||
i == sem::BuiltinType::kAtomicOr ||
i == sem::BuiltinType::kAtomicXor ||
i == sem::BuiltinType::kAtomicExchange ||
i == sem::BuiltinType::kAtomicCompareExchangeWeak;
}
Builtin::Builtin(BuiltinType type,
const sem::Type* return_type,
std::vector<Parameter*> parameters,
PipelineStageSet supported_stages,
bool is_deprecated)
: Base(return_type, utils::ToConstPtrVec(parameters)),
type_(type),
supported_stages_(supported_stages),
is_deprecated_(is_deprecated) {
for (auto* parameter : parameters) {
parameter->SetOwner(this);
}
}
Builtin::~Builtin() = default;
bool Builtin::IsCoarseDerivative() const {
return IsCoarseDerivativeBuiltin(type_);
}
bool Builtin::IsFineDerivative() const {
return IsFineDerivativeBuiltin(type_);
}
bool Builtin::IsDerivative() const {
return IsDerivativeBuiltin(type_);
}
bool Builtin::IsFloatClassification() const {
return IsFloatClassificationBuiltin(type_);
}
bool Builtin::IsTexture() const {
return IsTextureBuiltin(type_);
}
bool Builtin::IsImageQuery() const {
return IsImageQueryBuiltin(type_);
}
bool Builtin::IsDataPacking() const {
return IsDataPackingBuiltin(type_);
}
bool Builtin::IsDataUnpacking() const {
return IsDataUnpackingBuiltin(type_);
}
bool Builtin::IsBarrier() const {
return IsBarrierBuiltin(type_);
}
bool Builtin::IsAtomic() const {
return IsAtomicBuiltin(type_);
}
} // namespace sem
} // namespace tint
//! @endcond

173
src/sem/builtin.h Normal file
View File

@ -0,0 +1,173 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_SEM_BUILTIN_H_
#define SRC_SEM_BUILTIN_H_
#include <string>
#include <vector>
#include "src/sem/builtin_type.h"
#include "src/sem/call_target.h"
#include "src/sem/pipeline_stage_set.h"
#include "src/utils/hash.h"
namespace tint {
namespace sem {
/// Determines if the given `i` is a coarse derivative
/// @param i the builtin type
/// @returns true if the given derivative is coarse.
bool IsCoarseDerivativeBuiltin(BuiltinType i);
/// Determines if the given `i` is a fine derivative
/// @param i the builtin type
/// @returns true if the given derivative is fine.
bool IsFineDerivativeBuiltin(BuiltinType i);
/// Determine if the given `i` is a derivative builtin
/// @param i the builtin type
/// @returns true if the given `i` is a derivative builtin
bool IsDerivativeBuiltin(BuiltinType i);
/// Determines if the given `i` is a float classification builtin
/// @param i the builtin type
/// @returns true if the given `i` is a float builtin
bool IsFloatClassificationBuiltin(BuiltinType i);
/// Determines if the given `i` is a texture operation builtin
/// @param i the builtin type
/// @returns true if the given `i` is a texture operation builtin
bool IsTextureBuiltin(BuiltinType i);
/// Determines if the given `i` is a image query builtin
/// @param i the builtin type
/// @returns true if the given `i` is a image query builtin
bool IsImageQueryBuiltin(BuiltinType i);
/// Determines if the given `i` is a data packing builtin
/// @param i the builtin
/// @returns true if the given `i` is a data packing builtin
bool IsDataPackingBuiltin(BuiltinType i);
/// Determines if the given `i` is a data unpacking builtin
/// @param i the builtin
/// @returns true if the given `i` is a data unpacking builtin
bool IsDataUnpackingBuiltin(BuiltinType i);
/// Determines if the given `i` is a barrier builtin
/// @param i the builtin
/// @returns true if the given `i` is a barrier builtin
bool IsBarrierBuiltin(BuiltinType i);
/// Determines if the given `i` is a atomic builtin
/// @param i the builtin
/// @returns true if the given `i` is a atomic builtin
bool IsAtomicBuiltin(BuiltinType i);
/// Builtin holds the semantic information for a builtin function.
class Builtin : public Castable<Builtin, CallTarget> {
public:
/// Constructor
/// @param type the builtin type
/// @param return_type the return type for the builtin call
/// @param parameters the parameters for the builtin overload
/// @param supported_stages the pipeline stages that this builtin can be
/// used in
/// @param is_deprecated true if the particular overload is considered
/// deprecated
Builtin(BuiltinType type,
const sem::Type* return_type,
std::vector<Parameter*> parameters,
PipelineStageSet supported_stages,
bool is_deprecated);
/// Destructor
~Builtin() override;
/// @return the type of the builtin
BuiltinType Type() const { return type_; }
/// @return the pipeline stages that this builtin can be used in
PipelineStageSet SupportedStages() const { return supported_stages_; }
/// @return true if the builtin overload is considered deprecated
bool IsDeprecated() const { return is_deprecated_; }
/// @returns the name of the builtin function type. The spelling, including
/// case, matches the name in the WGSL spec.
const char* str() const;
/// @returns true if builtin is a coarse derivative builtin
bool IsCoarseDerivative() const;
/// @returns true if builtin is a fine a derivative builtin
bool IsFineDerivative() const;
/// @returns true if builtin is a derivative builtin
bool IsDerivative() const;
/// @returns true if builtin is a float builtin
bool IsFloatClassification() const;
/// @returns true if builtin is a texture operation builtin
bool IsTexture() const;
/// @returns true if builtin is a image query builtin
bool IsImageQuery() const;
/// @returns true if builtin is a data packing builtin
bool IsDataPacking() const;
/// @returns true if builtin is a data unpacking builtin
bool IsDataUnpacking() const;
/// @returns true if builtin is a barrier builtin
bool IsBarrier() const;
/// @returns true if builtin is a atomic builtin
bool IsAtomic() const;
private:
const BuiltinType type_;
const PipelineStageSet supported_stages_;
const bool is_deprecated_;
};
/// Constant value used by the degrees() builtin
static constexpr double kRadToDeg = 57.295779513082322865;
/// Constant value used by the radians() builtin
static constexpr double kDegToRad = 0.017453292519943295474;
} // namespace sem
} // namespace tint
namespace std {
/// Custom std::hash specialization for tint::sem::Builtin
template <>
class hash<tint::sem::Builtin> {
public:
/// @param i the Builtin to create a hash for
/// @return the hash value
inline std::size_t operator()(const tint::sem::Builtin& i) const {
return tint::utils::Hash(i.Type(), i.SupportedStages(), i.ReturnType(),
i.Parameters(), i.IsDeprecated());
}
};
} // namespace std
#endif // SRC_SEM_BUILTIN_H_

131
src/sem/builtin_test.cc Normal file
View File

@ -0,0 +1,131 @@
// 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/sem/builtin.h"
#include "gtest/gtest.h"
namespace tint {
namespace sem {
namespace {
struct BuiltinData {
const char* name;
BuiltinType builtin;
};
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
out << data.name;
return out;
}
using BuiltinTypeTest = testing::TestWithParam<BuiltinData>;
TEST_P(BuiltinTypeTest, Parse) {
auto param = GetParam();
EXPECT_EQ(ParseBuiltinType(param.name), param.builtin);
}
INSTANTIATE_TEST_SUITE_P(
BuiltinTypeTest,
BuiltinTypeTest,
testing::Values(
BuiltinData{"abs", BuiltinType::kAbs},
BuiltinData{"acos", BuiltinType::kAcos},
BuiltinData{"all", BuiltinType::kAll},
BuiltinData{"any", BuiltinType::kAny},
BuiltinData{"arrayLength", BuiltinType::kArrayLength},
BuiltinData{"asin", BuiltinType::kAsin},
BuiltinData{"atan", BuiltinType::kAtan},
BuiltinData{"atan2", BuiltinType::kAtan2},
BuiltinData{"ceil", BuiltinType::kCeil},
BuiltinData{"clamp", BuiltinType::kClamp},
BuiltinData{"cos", BuiltinType::kCos},
BuiltinData{"cosh", BuiltinType::kCosh},
BuiltinData{"countOneBits", BuiltinType::kCountOneBits},
BuiltinData{"cross", BuiltinType::kCross},
BuiltinData{"determinant", BuiltinType::kDeterminant},
BuiltinData{"distance", BuiltinType::kDistance},
BuiltinData{"dot", BuiltinType::kDot},
BuiltinData{"dpdx", BuiltinType::kDpdx},
BuiltinData{"dpdxCoarse", BuiltinType::kDpdxCoarse},
BuiltinData{"dpdxFine", BuiltinType::kDpdxFine},
BuiltinData{"dpdy", BuiltinType::kDpdy},
BuiltinData{"dpdyCoarse", BuiltinType::kDpdyCoarse},
BuiltinData{"dpdyFine", BuiltinType::kDpdyFine},
BuiltinData{"exp", BuiltinType::kExp},
BuiltinData{"exp2", BuiltinType::kExp2},
BuiltinData{"faceForward", BuiltinType::kFaceForward},
BuiltinData{"floor", BuiltinType::kFloor},
BuiltinData{"fma", BuiltinType::kFma},
BuiltinData{"fract", BuiltinType::kFract},
BuiltinData{"frexp", BuiltinType::kFrexp},
BuiltinData{"fwidth", BuiltinType::kFwidth},
BuiltinData{"fwidthCoarse", BuiltinType::kFwidthCoarse},
BuiltinData{"fwidthFine", BuiltinType::kFwidthFine},
BuiltinData{"inverseSqrt", BuiltinType::kInverseSqrt},
BuiltinData{"isFinite", BuiltinType::kIsFinite},
BuiltinData{"isInf", BuiltinType::kIsInf},
BuiltinData{"isNan", BuiltinType::kIsNan},
BuiltinData{"isNormal", BuiltinType::kIsNormal},
BuiltinData{"ldexp", BuiltinType::kLdexp},
BuiltinData{"length", BuiltinType::kLength},
BuiltinData{"log", BuiltinType::kLog},
BuiltinData{"log2", BuiltinType::kLog2},
BuiltinData{"max", BuiltinType::kMax},
BuiltinData{"min", BuiltinType::kMin},
BuiltinData{"mix", BuiltinType::kMix},
BuiltinData{"modf", BuiltinType::kModf},
BuiltinData{"normalize", BuiltinType::kNormalize},
BuiltinData{"pow", BuiltinType::kPow},
BuiltinData{"reflect", BuiltinType::kReflect},
BuiltinData{"reverseBits", BuiltinType::kReverseBits},
BuiltinData{"round", BuiltinType::kRound},
BuiltinData{"select", BuiltinType::kSelect},
BuiltinData{"sign", BuiltinType::kSign},
BuiltinData{"sin", BuiltinType::kSin},
BuiltinData{"sinh", BuiltinType::kSinh},
BuiltinData{"smoothStep", BuiltinType::kSmoothStep},
BuiltinData{"sqrt", BuiltinType::kSqrt},
BuiltinData{"step", BuiltinType::kStep},
BuiltinData{"storageBarrier", BuiltinType::kStorageBarrier},
BuiltinData{"tan", BuiltinType::kTan},
BuiltinData{"tanh", BuiltinType::kTanh},
BuiltinData{"textureDimensions", BuiltinType::kTextureDimensions},
BuiltinData{"textureLoad", BuiltinType::kTextureLoad},
BuiltinData{"textureNumLayers", BuiltinType::kTextureNumLayers},
BuiltinData{"textureNumLevels", BuiltinType::kTextureNumLevels},
BuiltinData{"textureNumSamples", BuiltinType::kTextureNumSamples},
BuiltinData{"textureSample", BuiltinType::kTextureSample},
BuiltinData{"textureSampleBias", BuiltinType::kTextureSampleBias},
BuiltinData{"textureSampleCompare", BuiltinType::kTextureSampleCompare},
BuiltinData{"textureSampleCompareLevel",
BuiltinType::kTextureSampleCompareLevel},
BuiltinData{"textureSampleGrad", BuiltinType::kTextureSampleGrad},
BuiltinData{"textureSampleLevel", BuiltinType::kTextureSampleLevel},
BuiltinData{"trunc", BuiltinType::kTrunc},
BuiltinData{"unpack2x16float", BuiltinType::kUnpack2x16float},
BuiltinData{"unpack2x16snorm", BuiltinType::kUnpack2x16snorm},
BuiltinData{"unpack2x16unorm", BuiltinType::kUnpack2x16unorm},
BuiltinData{"unpack4x8snorm", BuiltinType::kUnpack4x8snorm},
BuiltinData{"unpack4x8unorm", BuiltinType::kUnpack4x8unorm},
BuiltinData{"workgroupBarrier", BuiltinType::kWorkgroupBarrier}));
TEST_F(BuiltinTypeTest, ParseNoMatch) {
EXPECT_EQ(ParseBuiltinType("not_builtin"), BuiltinType::kNone);
}
} // namespace
} // namespace sem
} // namespace tint

560
src/sem/builtin_type.cc Normal file
View File

@ -0,0 +1,560 @@
// 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/builtin-gen
// using the template:
// src/sem/builtin_type.cc.tmpl
// and the builtin defintion file:
// src/builtins.def
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
#include "src/sem/builtin_type.h"
#include <sstream>
namespace tint {
namespace sem {
BuiltinType ParseBuiltinType(const std::string& name) {
if (name == "abs") {
return BuiltinType::kAbs;
}
if (name == "acos") {
return BuiltinType::kAcos;
}
if (name == "all") {
return BuiltinType::kAll;
}
if (name == "any") {
return BuiltinType::kAny;
}
if (name == "arrayLength") {
return BuiltinType::kArrayLength;
}
if (name == "asin") {
return BuiltinType::kAsin;
}
if (name == "atan") {
return BuiltinType::kAtan;
}
if (name == "atan2") {
return BuiltinType::kAtan2;
}
if (name == "ceil") {
return BuiltinType::kCeil;
}
if (name == "clamp") {
return BuiltinType::kClamp;
}
if (name == "cos") {
return BuiltinType::kCos;
}
if (name == "cosh") {
return BuiltinType::kCosh;
}
if (name == "countOneBits") {
return BuiltinType::kCountOneBits;
}
if (name == "cross") {
return BuiltinType::kCross;
}
if (name == "degrees") {
return BuiltinType::kDegrees;
}
if (name == "determinant") {
return BuiltinType::kDeterminant;
}
if (name == "distance") {
return BuiltinType::kDistance;
}
if (name == "dot") {
return BuiltinType::kDot;
}
if (name == "dpdx") {
return BuiltinType::kDpdx;
}
if (name == "dpdxCoarse") {
return BuiltinType::kDpdxCoarse;
}
if (name == "dpdxFine") {
return BuiltinType::kDpdxFine;
}
if (name == "dpdy") {
return BuiltinType::kDpdy;
}
if (name == "dpdyCoarse") {
return BuiltinType::kDpdyCoarse;
}
if (name == "dpdyFine") {
return BuiltinType::kDpdyFine;
}
if (name == "exp") {
return BuiltinType::kExp;
}
if (name == "exp2") {
return BuiltinType::kExp2;
}
if (name == "faceForward") {
return BuiltinType::kFaceForward;
}
if (name == "floor") {
return BuiltinType::kFloor;
}
if (name == "fma") {
return BuiltinType::kFma;
}
if (name == "fract") {
return BuiltinType::kFract;
}
if (name == "frexp") {
return BuiltinType::kFrexp;
}
if (name == "fwidth") {
return BuiltinType::kFwidth;
}
if (name == "fwidthCoarse") {
return BuiltinType::kFwidthCoarse;
}
if (name == "fwidthFine") {
return BuiltinType::kFwidthFine;
}
if (name == "inverseSqrt") {
return BuiltinType::kInverseSqrt;
}
if (name == "isFinite") {
return BuiltinType::kIsFinite;
}
if (name == "isInf") {
return BuiltinType::kIsInf;
}
if (name == "isNan") {
return BuiltinType::kIsNan;
}
if (name == "isNormal") {
return BuiltinType::kIsNormal;
}
if (name == "ldexp") {
return BuiltinType::kLdexp;
}
if (name == "length") {
return BuiltinType::kLength;
}
if (name == "log") {
return BuiltinType::kLog;
}
if (name == "log2") {
return BuiltinType::kLog2;
}
if (name == "max") {
return BuiltinType::kMax;
}
if (name == "min") {
return BuiltinType::kMin;
}
if (name == "mix") {
return BuiltinType::kMix;
}
if (name == "modf") {
return BuiltinType::kModf;
}
if (name == "normalize") {
return BuiltinType::kNormalize;
}
if (name == "pack2x16float") {
return BuiltinType::kPack2x16float;
}
if (name == "pack2x16snorm") {
return BuiltinType::kPack2x16snorm;
}
if (name == "pack2x16unorm") {
return BuiltinType::kPack2x16unorm;
}
if (name == "pack4x8snorm") {
return BuiltinType::kPack4x8snorm;
}
if (name == "pack4x8unorm") {
return BuiltinType::kPack4x8unorm;
}
if (name == "pow") {
return BuiltinType::kPow;
}
if (name == "radians") {
return BuiltinType::kRadians;
}
if (name == "reflect") {
return BuiltinType::kReflect;
}
if (name == "refract") {
return BuiltinType::kRefract;
}
if (name == "reverseBits") {
return BuiltinType::kReverseBits;
}
if (name == "round") {
return BuiltinType::kRound;
}
if (name == "select") {
return BuiltinType::kSelect;
}
if (name == "sign") {
return BuiltinType::kSign;
}
if (name == "sin") {
return BuiltinType::kSin;
}
if (name == "sinh") {
return BuiltinType::kSinh;
}
if (name == "smoothStep") {
return BuiltinType::kSmoothStep;
}
if (name == "sqrt") {
return BuiltinType::kSqrt;
}
if (name == "step") {
return BuiltinType::kStep;
}
if (name == "storageBarrier") {
return BuiltinType::kStorageBarrier;
}
if (name == "tan") {
return BuiltinType::kTan;
}
if (name == "tanh") {
return BuiltinType::kTanh;
}
if (name == "transpose") {
return BuiltinType::kTranspose;
}
if (name == "trunc") {
return BuiltinType::kTrunc;
}
if (name == "unpack2x16float") {
return BuiltinType::kUnpack2x16float;
}
if (name == "unpack2x16snorm") {
return BuiltinType::kUnpack2x16snorm;
}
if (name == "unpack2x16unorm") {
return BuiltinType::kUnpack2x16unorm;
}
if (name == "unpack4x8snorm") {
return BuiltinType::kUnpack4x8snorm;
}
if (name == "unpack4x8unorm") {
return BuiltinType::kUnpack4x8unorm;
}
if (name == "workgroupBarrier") {
return BuiltinType::kWorkgroupBarrier;
}
if (name == "textureDimensions") {
return BuiltinType::kTextureDimensions;
}
if (name == "textureGather") {
return BuiltinType::kTextureGather;
}
if (name == "textureGatherCompare") {
return BuiltinType::kTextureGatherCompare;
}
if (name == "textureNumLayers") {
return BuiltinType::kTextureNumLayers;
}
if (name == "textureNumLevels") {
return BuiltinType::kTextureNumLevels;
}
if (name == "textureNumSamples") {
return BuiltinType::kTextureNumSamples;
}
if (name == "textureSample") {
return BuiltinType::kTextureSample;
}
if (name == "textureSampleBias") {
return BuiltinType::kTextureSampleBias;
}
if (name == "textureSampleCompare") {
return BuiltinType::kTextureSampleCompare;
}
if (name == "textureSampleCompareLevel") {
return BuiltinType::kTextureSampleCompareLevel;
}
if (name == "textureSampleGrad") {
return BuiltinType::kTextureSampleGrad;
}
if (name == "textureSampleLevel") {
return BuiltinType::kTextureSampleLevel;
}
if (name == "textureStore") {
return BuiltinType::kTextureStore;
}
if (name == "textureLoad") {
return BuiltinType::kTextureLoad;
}
if (name == "atomicLoad") {
return BuiltinType::kAtomicLoad;
}
if (name == "atomicStore") {
return BuiltinType::kAtomicStore;
}
if (name == "atomicAdd") {
return BuiltinType::kAtomicAdd;
}
if (name == "atomicSub") {
return BuiltinType::kAtomicSub;
}
if (name == "atomicMax") {
return BuiltinType::kAtomicMax;
}
if (name == "atomicMin") {
return BuiltinType::kAtomicMin;
}
if (name == "atomicAnd") {
return BuiltinType::kAtomicAnd;
}
if (name == "atomicOr") {
return BuiltinType::kAtomicOr;
}
if (name == "atomicXor") {
return BuiltinType::kAtomicXor;
}
if (name == "atomicExchange") {
return BuiltinType::kAtomicExchange;
}
if (name == "atomicCompareExchangeWeak") {
return BuiltinType::kAtomicCompareExchangeWeak;
}
return BuiltinType::kNone;
}
const char* str(BuiltinType i) {
switch (i) {
case BuiltinType::kNone:
return "<none>";
case BuiltinType::kAbs:
return "abs";
case BuiltinType::kAcos:
return "acos";
case BuiltinType::kAll:
return "all";
case BuiltinType::kAny:
return "any";
case BuiltinType::kArrayLength:
return "arrayLength";
case BuiltinType::kAsin:
return "asin";
case BuiltinType::kAtan:
return "atan";
case BuiltinType::kAtan2:
return "atan2";
case BuiltinType::kCeil:
return "ceil";
case BuiltinType::kClamp:
return "clamp";
case BuiltinType::kCos:
return "cos";
case BuiltinType::kCosh:
return "cosh";
case BuiltinType::kCountOneBits:
return "countOneBits";
case BuiltinType::kCross:
return "cross";
case BuiltinType::kDegrees:
return "degrees";
case BuiltinType::kDeterminant:
return "determinant";
case BuiltinType::kDistance:
return "distance";
case BuiltinType::kDot:
return "dot";
case BuiltinType::kDpdx:
return "dpdx";
case BuiltinType::kDpdxCoarse:
return "dpdxCoarse";
case BuiltinType::kDpdxFine:
return "dpdxFine";
case BuiltinType::kDpdy:
return "dpdy";
case BuiltinType::kDpdyCoarse:
return "dpdyCoarse";
case BuiltinType::kDpdyFine:
return "dpdyFine";
case BuiltinType::kExp:
return "exp";
case BuiltinType::kExp2:
return "exp2";
case BuiltinType::kFaceForward:
return "faceForward";
case BuiltinType::kFloor:
return "floor";
case BuiltinType::kFma:
return "fma";
case BuiltinType::kFract:
return "fract";
case BuiltinType::kFrexp:
return "frexp";
case BuiltinType::kFwidth:
return "fwidth";
case BuiltinType::kFwidthCoarse:
return "fwidthCoarse";
case BuiltinType::kFwidthFine:
return "fwidthFine";
case BuiltinType::kInverseSqrt:
return "inverseSqrt";
case BuiltinType::kIsFinite:
return "isFinite";
case BuiltinType::kIsInf:
return "isInf";
case BuiltinType::kIsNan:
return "isNan";
case BuiltinType::kIsNormal:
return "isNormal";
case BuiltinType::kLdexp:
return "ldexp";
case BuiltinType::kLength:
return "length";
case BuiltinType::kLog:
return "log";
case BuiltinType::kLog2:
return "log2";
case BuiltinType::kMax:
return "max";
case BuiltinType::kMin:
return "min";
case BuiltinType::kMix:
return "mix";
case BuiltinType::kModf:
return "modf";
case BuiltinType::kNormalize:
return "normalize";
case BuiltinType::kPack2x16float:
return "pack2x16float";
case BuiltinType::kPack2x16snorm:
return "pack2x16snorm";
case BuiltinType::kPack2x16unorm:
return "pack2x16unorm";
case BuiltinType::kPack4x8snorm:
return "pack4x8snorm";
case BuiltinType::kPack4x8unorm:
return "pack4x8unorm";
case BuiltinType::kPow:
return "pow";
case BuiltinType::kRadians:
return "radians";
case BuiltinType::kReflect:
return "reflect";
case BuiltinType::kRefract:
return "refract";
case BuiltinType::kReverseBits:
return "reverseBits";
case BuiltinType::kRound:
return "round";
case BuiltinType::kSelect:
return "select";
case BuiltinType::kSign:
return "sign";
case BuiltinType::kSin:
return "sin";
case BuiltinType::kSinh:
return "sinh";
case BuiltinType::kSmoothStep:
return "smoothStep";
case BuiltinType::kSqrt:
return "sqrt";
case BuiltinType::kStep:
return "step";
case BuiltinType::kStorageBarrier:
return "storageBarrier";
case BuiltinType::kTan:
return "tan";
case BuiltinType::kTanh:
return "tanh";
case BuiltinType::kTranspose:
return "transpose";
case BuiltinType::kTrunc:
return "trunc";
case BuiltinType::kUnpack2x16float:
return "unpack2x16float";
case BuiltinType::kUnpack2x16snorm:
return "unpack2x16snorm";
case BuiltinType::kUnpack2x16unorm:
return "unpack2x16unorm";
case BuiltinType::kUnpack4x8snorm:
return "unpack4x8snorm";
case BuiltinType::kUnpack4x8unorm:
return "unpack4x8unorm";
case BuiltinType::kWorkgroupBarrier:
return "workgroupBarrier";
case BuiltinType::kTextureDimensions:
return "textureDimensions";
case BuiltinType::kTextureGather:
return "textureGather";
case BuiltinType::kTextureGatherCompare:
return "textureGatherCompare";
case BuiltinType::kTextureNumLayers:
return "textureNumLayers";
case BuiltinType::kTextureNumLevels:
return "textureNumLevels";
case BuiltinType::kTextureNumSamples:
return "textureNumSamples";
case BuiltinType::kTextureSample:
return "textureSample";
case BuiltinType::kTextureSampleBias:
return "textureSampleBias";
case BuiltinType::kTextureSampleCompare:
return "textureSampleCompare";
case BuiltinType::kTextureSampleCompareLevel:
return "textureSampleCompareLevel";
case BuiltinType::kTextureSampleGrad:
return "textureSampleGrad";
case BuiltinType::kTextureSampleLevel:
return "textureSampleLevel";
case BuiltinType::kTextureStore:
return "textureStore";
case BuiltinType::kTextureLoad:
return "textureLoad";
case BuiltinType::kAtomicLoad:
return "atomicLoad";
case BuiltinType::kAtomicStore:
return "atomicStore";
case BuiltinType::kAtomicAdd:
return "atomicAdd";
case BuiltinType::kAtomicSub:
return "atomicSub";
case BuiltinType::kAtomicMax:
return "atomicMax";
case BuiltinType::kAtomicMin:
return "atomicMin";
case BuiltinType::kAtomicAnd:
return "atomicAnd";
case BuiltinType::kAtomicOr:
return "atomicOr";
case BuiltinType::kAtomicXor:
return "atomicXor";
case BuiltinType::kAtomicExchange:
return "atomicExchange";
case BuiltinType::kAtomicCompareExchangeWeak:
return "atomicCompareExchangeWeak";
}
return "<unknown>";
}
std::ostream& operator<<(std::ostream& out, BuiltinType i) {
out << str(i);
return out;
}
} // namespace sem
} // namespace tint

View File

@ -1,42 +1,42 @@
{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/intrinsic-gen to generate intrinsic_type.cc
Template file for use with tools/builtin-gen to generate builtin_type.cc
See:
* tools/cmd/intrinsic-gen/gen for structures used by this template
* tools/cmd/builtin-gen/gen for structures used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}
#include "src/sem/intrinsic_type.h"
#include "src/sem/builtin_type.h"
#include <sstream>
namespace tint {
namespace sem {
IntrinsicType ParseIntrinsicType(const std::string& name) {
BuiltinType ParseBuiltinType(const std::string& name) {
{{- range .Sem.Functions }}
if (name == "{{.Name}}") {
return IntrinsicType::k{{Title .Name}};
return BuiltinType::k{{Title .Name}};
}
{{- end }}
return IntrinsicType::kNone;
return BuiltinType::kNone;
}
const char* str(IntrinsicType i) {
const char* str(BuiltinType i) {
switch (i) {
case IntrinsicType::kNone:
case BuiltinType::kNone:
return "<none>";
{{- range .Sem.Functions }}
case IntrinsicType::k{{Title .Name}}:
case BuiltinType::k{{Title .Name}}:
return "{{.Name}}";
{{- end }}
}
return "<unknown>";
}
std::ostream& operator<<(std::ostream& out, IntrinsicType i) {
std::ostream& operator<<(std::ostream& out, BuiltinType i) {
out << str(i);
return out;
}

View File

@ -13,17 +13,17 @@
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// File generated by tools/intrinsic-gen
// File generated by tools/builtin-gen
// using the template:
// src/sem/intrinsic_type.h.tmpl
// and the intrinsic defintion file:
// src/intrinsics.def
// src/sem/builtin_type.h.tmpl
// and the builtin defintion file:
// src/builtins.def
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
#ifndef SRC_SEM_INTRINSIC_TYPE_H_
#define SRC_SEM_INTRINSIC_TYPE_H_
#ifndef SRC_SEM_BUILTIN_TYPE_H_
#define SRC_SEM_BUILTIN_TYPE_H_
#include <sstream>
#include <string>
@ -31,8 +31,8 @@
namespace tint {
namespace sem {
/// Enumerator of all intrinsic functions
enum class IntrinsicType {
/// Enumerator of all builtin functions
enum class BuiltinType {
kNone = -1,
kAbs,
kAcos,
@ -138,21 +138,21 @@ enum class IntrinsicType {
kAtomicCompareExchangeWeak,
};
/// Matches the IntrinsicType by name
/// @param name the intrinsic name to parse
/// @returns the parsed IntrinsicType, or IntrinsicType::kNone if `name` did not
/// match any intrinsic.
IntrinsicType ParseIntrinsicType(const std::string& name);
/// Matches the BuiltinType by name
/// @param name the builtin name to parse
/// @returns the parsed BuiltinType, or BuiltinType::kNone if `name` did not
/// match any builtin.
BuiltinType ParseBuiltinType(const std::string& name);
/// @returns the name of the intrinsic function type. The spelling, including
/// @returns the name of the builtin function type. The spelling, including
/// case, matches the name in the WGSL spec.
const char* str(IntrinsicType i);
const char* str(BuiltinType i);
/// Emits the name of the intrinsic function type. The spelling, including case,
/// Emits the name of the builtin function type. The spelling, including case,
/// matches the name in the WGSL spec.
std::ostream& operator<<(std::ostream& out, IntrinsicType i);
std::ostream& operator<<(std::ostream& out, BuiltinType i);
} // namespace sem
} // namespace tint
#endif // SRC_SEM_INTRINSIC_TYPE_H_
#endif // SRC_SEM_BUILTIN_TYPE_H_

View File

@ -0,0 +1,45 @@
{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/builtin-gen to generate builtin_type.h
See:
* tools/cmd/builtin-gen/gen for structures used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}
#ifndef SRC_SEM_BUILTIN_TYPE_H_
#define SRC_SEM_BUILTIN_TYPE_H_
#include <sstream>
#include <string>
namespace tint {
namespace sem {
/// Enumerator of all builtin functions
enum class BuiltinType {
kNone = -1,
{{- range .Sem.Functions }}
k{{Title .Name}},
{{- end }}
};
/// Matches the BuiltinType by name
/// @param name the builtin name to parse
/// @returns the parsed BuiltinType, or BuiltinType::kNone if `name` did not
/// match any builtin.
BuiltinType ParseBuiltinType(const std::string& name);
/// @returns the name of the builtin function type. The spelling, including
/// case, matches the name in the WGSL spec.
const char* str(BuiltinType i);
/// Emits the name of the builtin function type. The spelling, including case,
/// matches the name in the WGSL spec.
std::ostream& operator<<(std::ostream& out, BuiltinType i);
} // namespace sem
} // namespace tint
#endif // SRC_SEM_BUILTIN_TYPE_H_

View File

@ -17,8 +17,8 @@
#include <vector>
#include "src/sem/builtin.h"
#include "src/sem/expression.h"
#include "src/sem/intrinsic.h"
namespace tint {
namespace sem {

View File

@ -56,7 +56,7 @@ struct CallTargetSignature {
int IndexOf(ParameterUsage usage) const;
};
/// CallTarget is the base for callable functions, intrinsics, type constructors
/// CallTarget is the base for callable functions, builtins, type constructors
/// and type casts.
class CallTarget : public Castable<CallTarget, Node> {
public:

View File

@ -35,7 +35,7 @@ class ReturnStatement;
namespace sem {
class Intrinsic;
class Builtin;
class Variable;
/// WorkgroupDimension describes the size of a single dimension of an entry
@ -120,16 +120,15 @@ class Function : public Castable<Function, CallTarget> {
transitively_called_functions_.add(function);
}
/// @returns the list of intrinsics that this function directly calls.
const utils::UniqueVector<const Intrinsic*>& DirectlyCalledIntrinsics()
const {
return directly_called_intrinsics_;
/// @returns the list of builtins that this function directly calls.
const utils::UniqueVector<const Builtin*>& DirectlyCalledBuiltins() const {
return directly_called_builtins_;
}
/// Records that this function transitively calls `intrinsic`.
/// @param intrinsic the intrinsic this function directly calls
void AddDirectlyCalledIntrinsic(const Intrinsic* intrinsic) {
directly_called_intrinsics_.add(intrinsic);
/// Records that this function transitively calls `builtin`.
/// @param builtin the builtin this function directly calls
void AddDirectlyCalledBuiltin(const Builtin* builtin) {
directly_called_builtins_.add(builtin);
}
/// Adds the given texture/sampler pair to the list of unique pairs
@ -149,13 +148,13 @@ class Function : public Castable<Function, CallTarget> {
return texture_sampler_pairs_;
}
/// @returns the list of direct calls to functions / intrinsics made by this
/// @returns the list of direct calls to functions / builtins made by this
/// function
std::vector<const Call*> DirectCallStatements() const {
return direct_calls_;
}
/// Adds a record of the direct function / intrinsic calls made by this
/// Adds a record of the direct function / builtin calls made by this
/// function
/// @param call the call
void AddDirectCall(const Call* call) { direct_calls_.emplace_back(call); }
@ -275,7 +274,7 @@ class Function : public Castable<Function, CallTarget> {
utils::UniqueVector<const GlobalVariable*> directly_referenced_globals_;
utils::UniqueVector<const GlobalVariable*> transitively_referenced_globals_;
utils::UniqueVector<const Function*> transitively_called_functions_;
utils::UniqueVector<const Intrinsic*> directly_called_intrinsics_;
utils::UniqueVector<const Builtin*> directly_called_builtins_;
utils::UniqueVector<VariablePair> texture_sampler_pairs_;
std::vector<const Call*> direct_calls_;
std::vector<const Call*> callsites_;

View File

@ -1,163 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/sem/intrinsic.h"
#include <vector>
#include "src/utils/to_const_ptr_vec.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Intrinsic);
namespace tint {
namespace sem {
const char* Intrinsic::str() const {
return sem::str(type_);
}
bool IsCoarseDerivativeIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kDpdxCoarse || i == IntrinsicType::kDpdyCoarse ||
i == IntrinsicType::kFwidthCoarse;
}
bool IsFineDerivativeIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kDpdxFine || i == IntrinsicType::kDpdyFine ||
i == IntrinsicType::kFwidthFine;
}
bool IsDerivativeIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kDpdx || i == IntrinsicType::kDpdy ||
i == IntrinsicType::kFwidth || IsCoarseDerivativeIntrinsic(i) ||
IsFineDerivativeIntrinsic(i);
}
bool IsFloatClassificationIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kIsFinite || i == IntrinsicType::kIsInf ||
i == IntrinsicType::kIsNan || i == IntrinsicType::kIsNormal;
}
bool IsTextureIntrinsic(IntrinsicType i) {
return IsImageQueryIntrinsic(i) || i == IntrinsicType::kTextureLoad ||
i == IntrinsicType::kTextureGather ||
i == IntrinsicType::kTextureGatherCompare ||
i == IntrinsicType::kTextureSample ||
i == IntrinsicType::kTextureSampleLevel ||
i == IntrinsicType::kTextureSampleBias ||
i == IntrinsicType::kTextureSampleCompare ||
i == IntrinsicType::kTextureSampleCompareLevel ||
i == IntrinsicType::kTextureSampleGrad ||
i == IntrinsicType::kTextureStore;
}
bool IsImageQueryIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kTextureDimensions ||
i == IntrinsicType::kTextureNumLayers ||
i == IntrinsicType::kTextureNumLevels ||
i == IntrinsicType::kTextureNumSamples;
}
bool IsDataPackingIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kPack4x8snorm ||
i == IntrinsicType::kPack4x8unorm ||
i == IntrinsicType::kPack2x16snorm ||
i == IntrinsicType::kPack2x16unorm ||
i == IntrinsicType::kPack2x16float;
}
bool IsDataUnpackingIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kUnpack4x8snorm ||
i == IntrinsicType::kUnpack4x8unorm ||
i == IntrinsicType::kUnpack2x16snorm ||
i == IntrinsicType::kUnpack2x16unorm ||
i == IntrinsicType::kUnpack2x16float;
}
bool IsBarrierIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kWorkgroupBarrier ||
i == IntrinsicType::kStorageBarrier;
}
bool IsAtomicIntrinsic(IntrinsicType i) {
return i == sem::IntrinsicType::kAtomicLoad ||
i == sem::IntrinsicType::kAtomicStore ||
i == sem::IntrinsicType::kAtomicAdd ||
i == sem::IntrinsicType::kAtomicSub ||
i == sem::IntrinsicType::kAtomicMax ||
i == sem::IntrinsicType::kAtomicMin ||
i == sem::IntrinsicType::kAtomicAnd ||
i == sem::IntrinsicType::kAtomicOr ||
i == sem::IntrinsicType::kAtomicXor ||
i == sem::IntrinsicType::kAtomicExchange ||
i == sem::IntrinsicType::kAtomicCompareExchangeWeak;
}
Intrinsic::Intrinsic(IntrinsicType type,
const sem::Type* return_type,
std::vector<Parameter*> parameters,
PipelineStageSet supported_stages,
bool is_deprecated)
: Base(return_type, utils::ToConstPtrVec(parameters)),
type_(type),
supported_stages_(supported_stages),
is_deprecated_(is_deprecated) {
for (auto* parameter : parameters) {
parameter->SetOwner(this);
}
}
Intrinsic::~Intrinsic() = default;
bool Intrinsic::IsCoarseDerivative() const {
return IsCoarseDerivativeIntrinsic(type_);
}
bool Intrinsic::IsFineDerivative() const {
return IsFineDerivativeIntrinsic(type_);
}
bool Intrinsic::IsDerivative() const {
return IsDerivativeIntrinsic(type_);
}
bool Intrinsic::IsFloatClassification() const {
return IsFloatClassificationIntrinsic(type_);
}
bool Intrinsic::IsTexture() const {
return IsTextureIntrinsic(type_);
}
bool Intrinsic::IsImageQuery() const {
return IsImageQueryIntrinsic(type_);
}
bool Intrinsic::IsDataPacking() const {
return IsDataPackingIntrinsic(type_);
}
bool Intrinsic::IsDataUnpacking() const {
return IsDataUnpackingIntrinsic(type_);
}
bool Intrinsic::IsBarrier() const {
return IsBarrierIntrinsic(type_);
}
bool Intrinsic::IsAtomic() const {
return IsAtomicIntrinsic(type_);
}
} // namespace sem
} // namespace tint

View File

@ -1,173 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_SEM_INTRINSIC_H_
#define SRC_SEM_INTRINSIC_H_
#include <string>
#include <vector>
#include "src/sem/call_target.h"
#include "src/sem/intrinsic_type.h"
#include "src/sem/pipeline_stage_set.h"
#include "src/utils/hash.h"
namespace tint {
namespace sem {
/// Determines if the given `i` is a coarse derivative
/// @param i the intrinsic type
/// @returns true if the given derivative is coarse.
bool IsCoarseDerivativeIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a fine derivative
/// @param i the intrinsic type
/// @returns true if the given derivative is fine.
bool IsFineDerivativeIntrinsic(IntrinsicType i);
/// Determine if the given `i` is a derivative intrinsic
/// @param i the intrinsic type
/// @returns true if the given `i` is a derivative intrinsic
bool IsDerivativeIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a float classification intrinsic
/// @param i the intrinsic type
/// @returns true if the given `i` is a float intrinsic
bool IsFloatClassificationIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a texture operation intrinsic
/// @param i the intrinsic type
/// @returns true if the given `i` is a texture operation intrinsic
bool IsTextureIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a image query intrinsic
/// @param i the intrinsic type
/// @returns true if the given `i` is a image query intrinsic
bool IsImageQueryIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a data packing intrinsic
/// @param i the intrinsic
/// @returns true if the given `i` is a data packing intrinsic
bool IsDataPackingIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a data unpacking intrinsic
/// @param i the intrinsic
/// @returns true if the given `i` is a data unpacking intrinsic
bool IsDataUnpackingIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a barrier intrinsic
/// @param i the intrinsic
/// @returns true if the given `i` is a barrier intrinsic
bool IsBarrierIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a atomic intrinsic
/// @param i the intrinsic
/// @returns true if the given `i` is a atomic intrinsic
bool IsAtomicIntrinsic(IntrinsicType i);
/// Intrinsic holds the semantic information for an intrinsic function.
class Intrinsic : public Castable<Intrinsic, CallTarget> {
public:
/// Constructor
/// @param type the intrinsic type
/// @param return_type the return type for the intrinsic call
/// @param parameters the parameters for the intrinsic overload
/// @param supported_stages the pipeline stages that this intrinsic can be
/// used in
/// @param is_deprecated true if the particular overload is considered
/// deprecated
Intrinsic(IntrinsicType type,
const sem::Type* return_type,
std::vector<Parameter*> parameters,
PipelineStageSet supported_stages,
bool is_deprecated);
/// Destructor
~Intrinsic() override;
/// @return the type of the intrinsic
IntrinsicType Type() const { return type_; }
/// @return the pipeline stages that this intrinsic can be used in
PipelineStageSet SupportedStages() const { return supported_stages_; }
/// @return true if the intrinsic overload is considered deprecated
bool IsDeprecated() const { return is_deprecated_; }
/// @returns the name of the intrinsic function type. The spelling, including
/// case, matches the name in the WGSL spec.
const char* str() const;
/// @returns true if intrinsic is a coarse derivative intrinsic
bool IsCoarseDerivative() const;
/// @returns true if intrinsic is a fine a derivative intrinsic
bool IsFineDerivative() const;
/// @returns true if intrinsic is a derivative intrinsic
bool IsDerivative() const;
/// @returns true if intrinsic is a float intrinsic
bool IsFloatClassification() const;
/// @returns true if intrinsic is a texture operation intrinsic
bool IsTexture() const;
/// @returns true if intrinsic is a image query intrinsic
bool IsImageQuery() const;
/// @returns true if intrinsic is a data packing intrinsic
bool IsDataPacking() const;
/// @returns true if intrinsic is a data unpacking intrinsic
bool IsDataUnpacking() const;
/// @returns true if intrinsic is a barrier intrinsic
bool IsBarrier() const;
/// @returns true if intrinsic is a atomic intrinsic
bool IsAtomic() const;
private:
const IntrinsicType type_;
const PipelineStageSet supported_stages_;
const bool is_deprecated_;
};
/// Constant value used by the degrees() intrinsic
static constexpr double kRadToDeg = 57.295779513082322865;
/// Constant value used by the radians() intrinsic
static constexpr double kDegToRad = 0.017453292519943295474;
} // namespace sem
} // namespace tint
namespace std {
/// Custom std::hash specialization for tint::sem::Intrinsic
template <>
class hash<tint::sem::Intrinsic> {
public:
/// @param i the Intrinsic to create a hash for
/// @return the hash value
inline std::size_t operator()(const tint::sem::Intrinsic& i) const {
return tint::utils::Hash(i.Type(), i.SupportedStages(), i.ReturnType(),
i.Parameters(), i.IsDeprecated());
}
};
} // namespace std
#endif // SRC_SEM_INTRINSIC_H_

View File

@ -1,132 +0,0 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/sem/intrinsic.h"
#include "gtest/gtest.h"
namespace tint {
namespace sem {
namespace {
struct IntrinsicData {
const char* name;
IntrinsicType intrinsic;
};
inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
out << data.name;
return out;
}
using IntrinsicTypeTest = testing::TestWithParam<IntrinsicData>;
TEST_P(IntrinsicTypeTest, Parse) {
auto param = GetParam();
EXPECT_EQ(ParseIntrinsicType(param.name), param.intrinsic);
}
INSTANTIATE_TEST_SUITE_P(
IntrinsicTypeTest,
IntrinsicTypeTest,
testing::Values(
IntrinsicData{"abs", IntrinsicType::kAbs},
IntrinsicData{"acos", IntrinsicType::kAcos},
IntrinsicData{"all", IntrinsicType::kAll},
IntrinsicData{"any", IntrinsicType::kAny},
IntrinsicData{"arrayLength", IntrinsicType::kArrayLength},
IntrinsicData{"asin", IntrinsicType::kAsin},
IntrinsicData{"atan", IntrinsicType::kAtan},
IntrinsicData{"atan2", IntrinsicType::kAtan2},
IntrinsicData{"ceil", IntrinsicType::kCeil},
IntrinsicData{"clamp", IntrinsicType::kClamp},
IntrinsicData{"cos", IntrinsicType::kCos},
IntrinsicData{"cosh", IntrinsicType::kCosh},
IntrinsicData{"countOneBits", IntrinsicType::kCountOneBits},
IntrinsicData{"cross", IntrinsicType::kCross},
IntrinsicData{"determinant", IntrinsicType::kDeterminant},
IntrinsicData{"distance", IntrinsicType::kDistance},
IntrinsicData{"dot", IntrinsicType::kDot},
IntrinsicData{"dpdx", IntrinsicType::kDpdx},
IntrinsicData{"dpdxCoarse", IntrinsicType::kDpdxCoarse},
IntrinsicData{"dpdxFine", IntrinsicType::kDpdxFine},
IntrinsicData{"dpdy", IntrinsicType::kDpdy},
IntrinsicData{"dpdyCoarse", IntrinsicType::kDpdyCoarse},
IntrinsicData{"dpdyFine", IntrinsicType::kDpdyFine},
IntrinsicData{"exp", IntrinsicType::kExp},
IntrinsicData{"exp2", IntrinsicType::kExp2},
IntrinsicData{"faceForward", IntrinsicType::kFaceForward},
IntrinsicData{"floor", IntrinsicType::kFloor},
IntrinsicData{"fma", IntrinsicType::kFma},
IntrinsicData{"fract", IntrinsicType::kFract},
IntrinsicData{"frexp", IntrinsicType::kFrexp},
IntrinsicData{"fwidth", IntrinsicType::kFwidth},
IntrinsicData{"fwidthCoarse", IntrinsicType::kFwidthCoarse},
IntrinsicData{"fwidthFine", IntrinsicType::kFwidthFine},
IntrinsicData{"inverseSqrt", IntrinsicType::kInverseSqrt},
IntrinsicData{"isFinite", IntrinsicType::kIsFinite},
IntrinsicData{"isInf", IntrinsicType::kIsInf},
IntrinsicData{"isNan", IntrinsicType::kIsNan},
IntrinsicData{"isNormal", IntrinsicType::kIsNormal},
IntrinsicData{"ldexp", IntrinsicType::kLdexp},
IntrinsicData{"length", IntrinsicType::kLength},
IntrinsicData{"log", IntrinsicType::kLog},
IntrinsicData{"log2", IntrinsicType::kLog2},
IntrinsicData{"max", IntrinsicType::kMax},
IntrinsicData{"min", IntrinsicType::kMin},
IntrinsicData{"mix", IntrinsicType::kMix},
IntrinsicData{"modf", IntrinsicType::kModf},
IntrinsicData{"normalize", IntrinsicType::kNormalize},
IntrinsicData{"pow", IntrinsicType::kPow},
IntrinsicData{"reflect", IntrinsicType::kReflect},
IntrinsicData{"reverseBits", IntrinsicType::kReverseBits},
IntrinsicData{"round", IntrinsicType::kRound},
IntrinsicData{"select", IntrinsicType::kSelect},
IntrinsicData{"sign", IntrinsicType::kSign},
IntrinsicData{"sin", IntrinsicType::kSin},
IntrinsicData{"sinh", IntrinsicType::kSinh},
IntrinsicData{"smoothStep", IntrinsicType::kSmoothStep},
IntrinsicData{"sqrt", IntrinsicType::kSqrt},
IntrinsicData{"step", IntrinsicType::kStep},
IntrinsicData{"storageBarrier", IntrinsicType::kStorageBarrier},
IntrinsicData{"tan", IntrinsicType::kTan},
IntrinsicData{"tanh", IntrinsicType::kTanh},
IntrinsicData{"textureDimensions", IntrinsicType::kTextureDimensions},
IntrinsicData{"textureLoad", IntrinsicType::kTextureLoad},
IntrinsicData{"textureNumLayers", IntrinsicType::kTextureNumLayers},
IntrinsicData{"textureNumLevels", IntrinsicType::kTextureNumLevels},
IntrinsicData{"textureNumSamples", IntrinsicType::kTextureNumSamples},
IntrinsicData{"textureSample", IntrinsicType::kTextureSample},
IntrinsicData{"textureSampleBias", IntrinsicType::kTextureSampleBias},
IntrinsicData{"textureSampleCompare",
IntrinsicType::kTextureSampleCompare},
IntrinsicData{"textureSampleCompareLevel",
IntrinsicType::kTextureSampleCompareLevel},
IntrinsicData{"textureSampleGrad", IntrinsicType::kTextureSampleGrad},
IntrinsicData{"textureSampleLevel", IntrinsicType::kTextureSampleLevel},
IntrinsicData{"trunc", IntrinsicType::kTrunc},
IntrinsicData{"unpack2x16float", IntrinsicType::kUnpack2x16float},
IntrinsicData{"unpack2x16snorm", IntrinsicType::kUnpack2x16snorm},
IntrinsicData{"unpack2x16unorm", IntrinsicType::kUnpack2x16unorm},
IntrinsicData{"unpack4x8snorm", IntrinsicType::kUnpack4x8snorm},
IntrinsicData{"unpack4x8unorm", IntrinsicType::kUnpack4x8unorm},
IntrinsicData{"workgroupBarrier", IntrinsicType::kWorkgroupBarrier}));
TEST_F(IntrinsicTypeTest, ParseNoMatch) {
EXPECT_EQ(ParseIntrinsicType("not_intrinsic"), IntrinsicType::kNone);
}
} // namespace
} // namespace sem
} // namespace tint

View File

@ -1,560 +0,0 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// File generated by tools/intrinsic-gen
// using the template:
// src/sem/intrinsic_type.cc.tmpl
// and the intrinsic defintion file:
// src/intrinsics.def
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
#include "src/sem/intrinsic_type.h"
#include <sstream>
namespace tint {
namespace sem {
IntrinsicType ParseIntrinsicType(const std::string& name) {
if (name == "abs") {
return IntrinsicType::kAbs;
}
if (name == "acos") {
return IntrinsicType::kAcos;
}
if (name == "all") {
return IntrinsicType::kAll;
}
if (name == "any") {
return IntrinsicType::kAny;
}
if (name == "arrayLength") {
return IntrinsicType::kArrayLength;
}
if (name == "asin") {
return IntrinsicType::kAsin;
}
if (name == "atan") {
return IntrinsicType::kAtan;
}
if (name == "atan2") {
return IntrinsicType::kAtan2;
}
if (name == "ceil") {
return IntrinsicType::kCeil;
}
if (name == "clamp") {
return IntrinsicType::kClamp;
}
if (name == "cos") {
return IntrinsicType::kCos;
}
if (name == "cosh") {
return IntrinsicType::kCosh;
}
if (name == "countOneBits") {
return IntrinsicType::kCountOneBits;
}
if (name == "cross") {
return IntrinsicType::kCross;
}
if (name == "degrees") {
return IntrinsicType::kDegrees;
}
if (name == "determinant") {
return IntrinsicType::kDeterminant;
}
if (name == "distance") {
return IntrinsicType::kDistance;
}
if (name == "dot") {
return IntrinsicType::kDot;
}
if (name == "dpdx") {
return IntrinsicType::kDpdx;
}
if (name == "dpdxCoarse") {
return IntrinsicType::kDpdxCoarse;
}
if (name == "dpdxFine") {
return IntrinsicType::kDpdxFine;
}
if (name == "dpdy") {
return IntrinsicType::kDpdy;
}
if (name == "dpdyCoarse") {
return IntrinsicType::kDpdyCoarse;
}
if (name == "dpdyFine") {
return IntrinsicType::kDpdyFine;
}
if (name == "exp") {
return IntrinsicType::kExp;
}
if (name == "exp2") {
return IntrinsicType::kExp2;
}
if (name == "faceForward") {
return IntrinsicType::kFaceForward;
}
if (name == "floor") {
return IntrinsicType::kFloor;
}
if (name == "fma") {
return IntrinsicType::kFma;
}
if (name == "fract") {
return IntrinsicType::kFract;
}
if (name == "frexp") {
return IntrinsicType::kFrexp;
}
if (name == "fwidth") {
return IntrinsicType::kFwidth;
}
if (name == "fwidthCoarse") {
return IntrinsicType::kFwidthCoarse;
}
if (name == "fwidthFine") {
return IntrinsicType::kFwidthFine;
}
if (name == "inverseSqrt") {
return IntrinsicType::kInverseSqrt;
}
if (name == "isFinite") {
return IntrinsicType::kIsFinite;
}
if (name == "isInf") {
return IntrinsicType::kIsInf;
}
if (name == "isNan") {
return IntrinsicType::kIsNan;
}
if (name == "isNormal") {
return IntrinsicType::kIsNormal;
}
if (name == "ldexp") {
return IntrinsicType::kLdexp;
}
if (name == "length") {
return IntrinsicType::kLength;
}
if (name == "log") {
return IntrinsicType::kLog;
}
if (name == "log2") {
return IntrinsicType::kLog2;
}
if (name == "max") {
return IntrinsicType::kMax;
}
if (name == "min") {
return IntrinsicType::kMin;
}
if (name == "mix") {
return IntrinsicType::kMix;
}
if (name == "modf") {
return IntrinsicType::kModf;
}
if (name == "normalize") {
return IntrinsicType::kNormalize;
}
if (name == "pack2x16float") {
return IntrinsicType::kPack2x16float;
}
if (name == "pack2x16snorm") {
return IntrinsicType::kPack2x16snorm;
}
if (name == "pack2x16unorm") {
return IntrinsicType::kPack2x16unorm;
}
if (name == "pack4x8snorm") {
return IntrinsicType::kPack4x8snorm;
}
if (name == "pack4x8unorm") {
return IntrinsicType::kPack4x8unorm;
}
if (name == "pow") {
return IntrinsicType::kPow;
}
if (name == "radians") {
return IntrinsicType::kRadians;
}
if (name == "reflect") {
return IntrinsicType::kReflect;
}
if (name == "refract") {
return IntrinsicType::kRefract;
}
if (name == "reverseBits") {
return IntrinsicType::kReverseBits;
}
if (name == "round") {
return IntrinsicType::kRound;
}
if (name == "select") {
return IntrinsicType::kSelect;
}
if (name == "sign") {
return IntrinsicType::kSign;
}
if (name == "sin") {
return IntrinsicType::kSin;
}
if (name == "sinh") {
return IntrinsicType::kSinh;
}
if (name == "smoothStep") {
return IntrinsicType::kSmoothStep;
}
if (name == "sqrt") {
return IntrinsicType::kSqrt;
}
if (name == "step") {
return IntrinsicType::kStep;
}
if (name == "storageBarrier") {
return IntrinsicType::kStorageBarrier;
}
if (name == "tan") {
return IntrinsicType::kTan;
}
if (name == "tanh") {
return IntrinsicType::kTanh;
}
if (name == "transpose") {
return IntrinsicType::kTranspose;
}
if (name == "trunc") {
return IntrinsicType::kTrunc;
}
if (name == "unpack2x16float") {
return IntrinsicType::kUnpack2x16float;
}
if (name == "unpack2x16snorm") {
return IntrinsicType::kUnpack2x16snorm;
}
if (name == "unpack2x16unorm") {
return IntrinsicType::kUnpack2x16unorm;
}
if (name == "unpack4x8snorm") {
return IntrinsicType::kUnpack4x8snorm;
}
if (name == "unpack4x8unorm") {
return IntrinsicType::kUnpack4x8unorm;
}
if (name == "workgroupBarrier") {
return IntrinsicType::kWorkgroupBarrier;
}
if (name == "textureDimensions") {
return IntrinsicType::kTextureDimensions;
}
if (name == "textureGather") {
return IntrinsicType::kTextureGather;
}
if (name == "textureGatherCompare") {
return IntrinsicType::kTextureGatherCompare;
}
if (name == "textureNumLayers") {
return IntrinsicType::kTextureNumLayers;
}
if (name == "textureNumLevels") {
return IntrinsicType::kTextureNumLevels;
}
if (name == "textureNumSamples") {
return IntrinsicType::kTextureNumSamples;
}
if (name == "textureSample") {
return IntrinsicType::kTextureSample;
}
if (name == "textureSampleBias") {
return IntrinsicType::kTextureSampleBias;
}
if (name == "textureSampleCompare") {
return IntrinsicType::kTextureSampleCompare;
}
if (name == "textureSampleCompareLevel") {
return IntrinsicType::kTextureSampleCompareLevel;
}
if (name == "textureSampleGrad") {
return IntrinsicType::kTextureSampleGrad;
}
if (name == "textureSampleLevel") {
return IntrinsicType::kTextureSampleLevel;
}
if (name == "textureStore") {
return IntrinsicType::kTextureStore;
}
if (name == "textureLoad") {
return IntrinsicType::kTextureLoad;
}
if (name == "atomicLoad") {
return IntrinsicType::kAtomicLoad;
}
if (name == "atomicStore") {
return IntrinsicType::kAtomicStore;
}
if (name == "atomicAdd") {
return IntrinsicType::kAtomicAdd;
}
if (name == "atomicSub") {
return IntrinsicType::kAtomicSub;
}
if (name == "atomicMax") {
return IntrinsicType::kAtomicMax;
}
if (name == "atomicMin") {
return IntrinsicType::kAtomicMin;
}
if (name == "atomicAnd") {
return IntrinsicType::kAtomicAnd;
}
if (name == "atomicOr") {
return IntrinsicType::kAtomicOr;
}
if (name == "atomicXor") {
return IntrinsicType::kAtomicXor;
}
if (name == "atomicExchange") {
return IntrinsicType::kAtomicExchange;
}
if (name == "atomicCompareExchangeWeak") {
return IntrinsicType::kAtomicCompareExchangeWeak;
}
return IntrinsicType::kNone;
}
const char* str(IntrinsicType i) {
switch (i) {
case IntrinsicType::kNone:
return "<none>";
case IntrinsicType::kAbs:
return "abs";
case IntrinsicType::kAcos:
return "acos";
case IntrinsicType::kAll:
return "all";
case IntrinsicType::kAny:
return "any";
case IntrinsicType::kArrayLength:
return "arrayLength";
case IntrinsicType::kAsin:
return "asin";
case IntrinsicType::kAtan:
return "atan";
case IntrinsicType::kAtan2:
return "atan2";
case IntrinsicType::kCeil:
return "ceil";
case IntrinsicType::kClamp:
return "clamp";
case IntrinsicType::kCos:
return "cos";
case IntrinsicType::kCosh:
return "cosh";
case IntrinsicType::kCountOneBits:
return "countOneBits";
case IntrinsicType::kCross:
return "cross";
case IntrinsicType::kDegrees:
return "degrees";
case IntrinsicType::kDeterminant:
return "determinant";
case IntrinsicType::kDistance:
return "distance";
case IntrinsicType::kDot:
return "dot";
case IntrinsicType::kDpdx:
return "dpdx";
case IntrinsicType::kDpdxCoarse:
return "dpdxCoarse";
case IntrinsicType::kDpdxFine:
return "dpdxFine";
case IntrinsicType::kDpdy:
return "dpdy";
case IntrinsicType::kDpdyCoarse:
return "dpdyCoarse";
case IntrinsicType::kDpdyFine:
return "dpdyFine";
case IntrinsicType::kExp:
return "exp";
case IntrinsicType::kExp2:
return "exp2";
case IntrinsicType::kFaceForward:
return "faceForward";
case IntrinsicType::kFloor:
return "floor";
case IntrinsicType::kFma:
return "fma";
case IntrinsicType::kFract:
return "fract";
case IntrinsicType::kFrexp:
return "frexp";
case IntrinsicType::kFwidth:
return "fwidth";
case IntrinsicType::kFwidthCoarse:
return "fwidthCoarse";
case IntrinsicType::kFwidthFine:
return "fwidthFine";
case IntrinsicType::kInverseSqrt:
return "inverseSqrt";
case IntrinsicType::kIsFinite:
return "isFinite";
case IntrinsicType::kIsInf:
return "isInf";
case IntrinsicType::kIsNan:
return "isNan";
case IntrinsicType::kIsNormal:
return "isNormal";
case IntrinsicType::kLdexp:
return "ldexp";
case IntrinsicType::kLength:
return "length";
case IntrinsicType::kLog:
return "log";
case IntrinsicType::kLog2:
return "log2";
case IntrinsicType::kMax:
return "max";
case IntrinsicType::kMin:
return "min";
case IntrinsicType::kMix:
return "mix";
case IntrinsicType::kModf:
return "modf";
case IntrinsicType::kNormalize:
return "normalize";
case IntrinsicType::kPack2x16float:
return "pack2x16float";
case IntrinsicType::kPack2x16snorm:
return "pack2x16snorm";
case IntrinsicType::kPack2x16unorm:
return "pack2x16unorm";
case IntrinsicType::kPack4x8snorm:
return "pack4x8snorm";
case IntrinsicType::kPack4x8unorm:
return "pack4x8unorm";
case IntrinsicType::kPow:
return "pow";
case IntrinsicType::kRadians:
return "radians";
case IntrinsicType::kReflect:
return "reflect";
case IntrinsicType::kRefract:
return "refract";
case IntrinsicType::kReverseBits:
return "reverseBits";
case IntrinsicType::kRound:
return "round";
case IntrinsicType::kSelect:
return "select";
case IntrinsicType::kSign:
return "sign";
case IntrinsicType::kSin:
return "sin";
case IntrinsicType::kSinh:
return "sinh";
case IntrinsicType::kSmoothStep:
return "smoothStep";
case IntrinsicType::kSqrt:
return "sqrt";
case IntrinsicType::kStep:
return "step";
case IntrinsicType::kStorageBarrier:
return "storageBarrier";
case IntrinsicType::kTan:
return "tan";
case IntrinsicType::kTanh:
return "tanh";
case IntrinsicType::kTranspose:
return "transpose";
case IntrinsicType::kTrunc:
return "trunc";
case IntrinsicType::kUnpack2x16float:
return "unpack2x16float";
case IntrinsicType::kUnpack2x16snorm:
return "unpack2x16snorm";
case IntrinsicType::kUnpack2x16unorm:
return "unpack2x16unorm";
case IntrinsicType::kUnpack4x8snorm:
return "unpack4x8snorm";
case IntrinsicType::kUnpack4x8unorm:
return "unpack4x8unorm";
case IntrinsicType::kWorkgroupBarrier:
return "workgroupBarrier";
case IntrinsicType::kTextureDimensions:
return "textureDimensions";
case IntrinsicType::kTextureGather:
return "textureGather";
case IntrinsicType::kTextureGatherCompare:
return "textureGatherCompare";
case IntrinsicType::kTextureNumLayers:
return "textureNumLayers";
case IntrinsicType::kTextureNumLevels:
return "textureNumLevels";
case IntrinsicType::kTextureNumSamples:
return "textureNumSamples";
case IntrinsicType::kTextureSample:
return "textureSample";
case IntrinsicType::kTextureSampleBias:
return "textureSampleBias";
case IntrinsicType::kTextureSampleCompare:
return "textureSampleCompare";
case IntrinsicType::kTextureSampleCompareLevel:
return "textureSampleCompareLevel";
case IntrinsicType::kTextureSampleGrad:
return "textureSampleGrad";
case IntrinsicType::kTextureSampleLevel:
return "textureSampleLevel";
case IntrinsicType::kTextureStore:
return "textureStore";
case IntrinsicType::kTextureLoad:
return "textureLoad";
case IntrinsicType::kAtomicLoad:
return "atomicLoad";
case IntrinsicType::kAtomicStore:
return "atomicStore";
case IntrinsicType::kAtomicAdd:
return "atomicAdd";
case IntrinsicType::kAtomicSub:
return "atomicSub";
case IntrinsicType::kAtomicMax:
return "atomicMax";
case IntrinsicType::kAtomicMin:
return "atomicMin";
case IntrinsicType::kAtomicAnd:
return "atomicAnd";
case IntrinsicType::kAtomicOr:
return "atomicOr";
case IntrinsicType::kAtomicXor:
return "atomicXor";
case IntrinsicType::kAtomicExchange:
return "atomicExchange";
case IntrinsicType::kAtomicCompareExchangeWeak:
return "atomicCompareExchangeWeak";
}
return "<unknown>";
}
std::ostream& operator<<(std::ostream& out, IntrinsicType i) {
out << str(i);
return out;
}
} // namespace sem
} // namespace tint

View File

@ -1,45 +0,0 @@
{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/intrinsic-gen to generate intrinsic_type.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_SEM_INTRINSIC_TYPE_H_
#define SRC_SEM_INTRINSIC_TYPE_H_
#include <sstream>
#include <string>
namespace tint {
namespace sem {
/// Enumerator of all intrinsic functions
enum class IntrinsicType {
kNone = -1,
{{- range .Sem.Functions }}
k{{Title .Name}},
{{- end }}
};
/// Matches the IntrinsicType by name
/// @param name the intrinsic name to parse
/// @returns the parsed IntrinsicType, or IntrinsicType::kNone if `name` did not
/// match any intrinsic.
IntrinsicType ParseIntrinsicType(const std::string& name);
/// @returns the name of the intrinsic function type. The spelling, including
/// case, matches the name in the WGSL spec.
const char* str(IntrinsicType i);
/// Emits the name of the intrinsic function type. The spelling, including case,
/// matches the name in the WGSL spec.
std::ostream& operator<<(std::ostream& out, IntrinsicType i);
} // namespace sem
} // namespace tint
#endif // SRC_SEM_INTRINSIC_TYPE_H_

View File

@ -13,11 +13,11 @@
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// File generated by tools/intrinsic-gen
// File generated by tools/builtin-gen
// using the template:
// src/sem/parameter_usage.cc.tmpl
// and the intrinsic defintion file:
// src/intrinsics.def
// and the builtin defintion file:
// src/builtins.def
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////

View File

@ -1,9 +1,9 @@
{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/intrinsic-gen to generate parameter_usage.cc
Template file for use with tools/builtin-gen to generate parameter_usage.cc
See:
* tools/cmd/intrinsic-gen/gen for structures used by this template
* tools/cmd/builtin-gen/gen for structures used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}

View File

@ -13,11 +13,11 @@
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// File generated by tools/intrinsic-gen
// File generated by tools/builtin-gen
// using the template:
// src/sem/parameter_usage.h.tmpl
// and the intrinsic defintion file:
// src/intrinsics.def
// and the builtin defintion file:
// src/builtins.def
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////

View File

@ -1,9 +1,9 @@
{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/intrinsic-gen to generate parameter_usage.h
Template file for use with tools/builtin-gen to generate parameter_usage.h
See:
* tools/cmd/intrinsic-gen/gen for structures used by this template
* tools/cmd/builtin-gen/gen for structures used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}

View File

@ -34,7 +34,7 @@ namespace transform {
ArrayLengthFromUniform::ArrayLengthFromUniform() = default;
ArrayLengthFromUniform::~ArrayLengthFromUniform() = default;
/// Iterate over all arrayLength() intrinsics that operate on
/// Iterate over all arrayLength() builtins that operate on
/// storage buffer variables.
/// @param ctx the CloneContext.
/// @param functor of type void(const ast::CallExpression*, const
@ -46,7 +46,7 @@ template <typename F>
static void IterateArrayLengthOnStorageVar(CloneContext& ctx, F&& functor) {
auto& sem = ctx.src->Sem();
// Find all calls to the arrayLength() intrinsic.
// Find all calls to the arrayLength() builtin.
for (auto* node : ctx.src->ASTNodes().Objects()) {
auto* call_expr = node->As<ast::CallExpression>();
if (!call_expr) {
@ -54,8 +54,8 @@ static void IterateArrayLengthOnStorageVar(CloneContext& ctx, F&& functor) {
}
auto* call = sem.Get(call_expr);
auto* intrinsic = call->Target()->As<sem::Intrinsic>();
if (!intrinsic || intrinsic->Type() != sem::IntrinsicType::kArrayLength) {
auto* builtin = call->Target()->As<sem::Builtin>();
if (!builtin || builtin->Type() != sem::BuiltinType::kArrayLength) {
continue;
}
@ -98,8 +98,8 @@ bool ArrayLengthFromUniform::ShouldRun(const Program* program,
const DataMap&) const {
for (auto* fn : program->AST().Functions()) {
if (auto* sem_fn = program->Sem().Get(fn)) {
for (auto* intrinsic : sem_fn->DirectlyCalledIntrinsics()) {
if (intrinsic->Type() == sem::IntrinsicType::kArrayLength) {
for (auto* builtin : sem_fn->DirectlyCalledBuiltins()) {
if (builtin->Type() == sem::BuiltinType::kArrayLength) {
return true;
}
}

View File

@ -84,7 +84,7 @@ class ArrayLengthFromUniform
};
/// Information produced about what the transform did.
/// If there were no calls to the arrayLength() intrinsic, then no Result will
/// If there were no calls to the arrayLength() builtin, then no Result will
/// be emitted.
struct Result : public Castable<Result, transform::Data> {
/// Constructor

View File

@ -76,8 +76,8 @@ bool CalculateArrayLength::ShouldRun(const Program* program,
const DataMap&) const {
for (auto* fn : program->AST().Functions()) {
if (auto* sem_fn = program->Sem().Get(fn)) {
for (auto* intrinsic : sem_fn->DirectlyCalledIntrinsics()) {
if (intrinsic->Type() == sem::IntrinsicType::kArrayLength) {
for (auto* builtin : sem_fn->DirectlyCalledBuiltins()) {
if (builtin->Type() == sem::BuiltinType::kArrayLength) {
return true;
}
}
@ -143,8 +143,8 @@ void CalculateArrayLength::Run(CloneContext& ctx,
for (auto* node : ctx.src->ASTNodes().Objects()) {
if (auto* call_expr = node->As<ast::CallExpression>()) {
auto* call = sem.Get(call_expr);
if (auto* intrinsic = call->Target()->As<sem::Intrinsic>()) {
if (intrinsic->Type() == sem::IntrinsicType::kArrayLength) {
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
if (builtin->Type() == sem::BuiltinType::kArrayLength) {
// We're dealing with an arrayLength() call
// A runtime-sized array can only appear as the store type of a

View File

@ -71,7 +71,7 @@ struct CombineSamplers::State {
/// Placeholder global samplers used when a function contains texture-only
/// references (one comparison sampler, one regular). These are also used as
/// temporary sampler parameters to the texture intrinsics to satsify the WGSL
/// temporary sampler parameters to the texture builtins to satisfy the WGSL
/// resolver, but are then ignored and removed by the GLSL writer.
const ast::Variable* placeholder_samplers_[2] = {};
@ -210,9 +210,9 @@ struct CombineSamplers::State {
-> const ast::Expression* {
if (auto* call = sem.Get(expr)) {
ast::ExpressionList args;
// Replace all texture intrinsic calls.
if (auto* intrinsic = call->Target()->As<sem::Intrinsic>()) {
const auto& signature = intrinsic->Signature();
// Replace all texture builtin calls.
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
const auto& signature = builtin->Signature();
int sampler_index = signature.IndexOf(sem::ParameterUsage::kSampler);
int texture_index = signature.IndexOf(sem::ParameterUsage::kTexture);
if (texture_index == -1) {

View File

@ -38,9 +38,9 @@ namespace transform {
/// parameter. In this case, a new parameter is added to the function
/// signature. All separate texture/sampler parameters are removed.
///
/// All texture intrinsic callsites are modified to pass the combined
/// All texture builtin callsites are modified to pass the combined
/// texture/sampler as the first argument, and separate texture/sampler
/// arugments are removed.
/// arguments are removed.
///
/// Note that the sampler may be null, indicating that only a texture
/// reference was required (e.g., textureLoad). In this case, a

View File

@ -115,7 +115,7 @@ struct LoadStoreKey {
struct AtomicKey {
sem::Type const* buf_ty = nullptr; // buffer type
sem::Type const* el_ty = nullptr; // element type
sem::IntrinsicType const op; // atomic op
sem::BuiltinType const op; // atomic op
bool operator==(const AtomicKey& rhs) const {
return buf_ty == rhs.buf_ty && el_ty == rhs.el_ty && op == rhs.op;
}
@ -224,41 +224,41 @@ DecomposeMemoryAccess::Intrinsic* IntrinsicStoreFor(
/// @returns a DecomposeMemoryAccess::Intrinsic attribute that can be applied
/// to a stub function for the atomic op and the type `ty`.
DecomposeMemoryAccess::Intrinsic* IntrinsicAtomicFor(ProgramBuilder* builder,
sem::IntrinsicType ity,
sem::BuiltinType ity,
const sem::Type* ty) {
auto op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicLoad;
switch (ity) {
case sem::IntrinsicType::kAtomicLoad:
case sem::BuiltinType::kAtomicLoad:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicLoad;
break;
case sem::IntrinsicType::kAtomicStore:
case sem::BuiltinType::kAtomicStore:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicStore;
break;
case sem::IntrinsicType::kAtomicAdd:
case sem::BuiltinType::kAtomicAdd:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicAdd;
break;
case sem::IntrinsicType::kAtomicSub:
case sem::BuiltinType::kAtomicSub:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicSub;
break;
case sem::IntrinsicType::kAtomicMax:
case sem::BuiltinType::kAtomicMax:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicMax;
break;
case sem::IntrinsicType::kAtomicMin:
case sem::BuiltinType::kAtomicMin:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicMin;
break;
case sem::IntrinsicType::kAtomicAnd:
case sem::BuiltinType::kAtomicAnd:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicAnd;
break;
case sem::IntrinsicType::kAtomicOr:
case sem::BuiltinType::kAtomicOr:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicOr;
break;
case sem::IntrinsicType::kAtomicXor:
case sem::BuiltinType::kAtomicXor:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicXor;
break;
case sem::IntrinsicType::kAtomicExchange:
case sem::BuiltinType::kAtomicExchange:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicExchange;
break;
case sem::IntrinsicType::kAtomicCompareExchangeWeak:
case sem::BuiltinType::kAtomicCompareExchangeWeak:
op = DecomposeMemoryAccess::Intrinsic::Op::kAtomicCompareExchangeWeak;
break;
default:
@ -641,7 +641,7 @@ struct DecomposeMemoryAccess::State {
/// @return the name of the function that performs the load
Symbol AtomicFunc(const sem::Type* buf_ty,
const sem::Type* el_ty,
const sem::Intrinsic* intrinsic,
const sem::Builtin* intrinsic,
const sem::VariableUser* var_user) {
auto op = intrinsic->Type();
return utils::GetOrCreate(atomic_funcs, AtomicKey{buf_ty, el_ty, op}, [&] {
@ -921,15 +921,15 @@ void DecomposeMemoryAccess::Run(CloneContext& ctx,
if (auto* call_expr = node->As<ast::CallExpression>()) {
auto* call = sem.Get(call_expr);
if (auto* intrinsic = call->Target()->As<sem::Intrinsic>()) {
if (intrinsic->Type() == sem::IntrinsicType::kArrayLength) {
if (auto* builtin = call->Target()->As<sem::Builtin>()) {
if (builtin->Type() == sem::BuiltinType::kArrayLength) {
// arrayLength(X)
// Don't convert X into a load, this intrinsic actually requires the
// Don't convert X into a load, this builtin actually requires the
// real pointer.
state.TakeAccess(call_expr->args[0]);
continue;
}
if (intrinsic->IsAtomic()) {
if (builtin->IsAtomic()) {
if (auto access = state.TakeAccess(call_expr->args[0])) {
// atomic___(X)
ctx.Replace(call_expr, [=, &ctx, &state] {
@ -937,9 +937,8 @@ void DecomposeMemoryAccess::Run(CloneContext& ctx,
auto* offset = access.offset->Build(ctx);
auto* buf_ty = access.var->Type()->UnwrapRef();
auto* el_ty = access.type->UnwrapRef()->As<sem::Atomic>()->Type();
Symbol func =
state.AtomicFunc(buf_ty, el_ty, intrinsic,
access.var->As<sem::VariableUser>());
Symbol func = state.AtomicFunc(
buf_ty, el_ty, builtin, access.var->As<sem::VariableUser>());
ast::ExpressionList args{ctx.Clone(buf), offset};
for (size_t i = 1; i < call_expr->args.size(); i++) {

View File

@ -46,10 +46,9 @@ void ExternalTextureTransform::Run(CloneContext& ctx,
// Scan the AST nodes for calls to textureLoad or textureSampleLevel.
for (auto* node : ctx.src->ASTNodes().Objects()) {
if (auto* call_expr = node->As<ast::CallExpression>()) {
if (auto* intrinsic =
sem.Get(call_expr)->Target()->As<sem::Intrinsic>()) {
if (intrinsic->Type() == sem::IntrinsicType::kTextureLoad ||
intrinsic->Type() == sem::IntrinsicType::kTextureSampleLevel) {
if (auto* builtin = sem.Get(call_expr)->Target()->As<sem::Builtin>()) {
if (builtin->Type() == sem::BuiltinType::kTextureLoad ||
builtin->Type() == sem::BuiltinType::kTextureSampleLevel) {
// When a textureLoad or textureSampleLevel has been identified, check
// if the first parameter is an external texture.
if (auto* var =
@ -58,7 +57,7 @@ void ExternalTextureTransform::Run(CloneContext& ctx,
->Type()
->UnwrapRef()
->Is<sem::ExternalTexture>()) {
if (intrinsic->Type() == sem::IntrinsicType::kTextureLoad &&
if (builtin->Type() == sem::BuiltinType::kTextureLoad &&
call_expr->args.size() != 2) {
TINT_ICE(Transform, ctx.dst->Diagnostics())
<< "expected textureLoad call with a texture_external to "
@ -66,8 +65,7 @@ void ExternalTextureTransform::Run(CloneContext& ctx,
<< call_expr->args.size() << " parameters";
}
if (intrinsic->Type() ==
sem::IntrinsicType::kTextureSampleLevel &&
if (builtin->Type() == sem::BuiltinType::kTextureSampleLevel &&
call_expr->args.size() != 3) {
TINT_ICE(Transform, ctx.dst->Diagnostics())
<< "expected textureSampleLevel call with a "
@ -82,12 +80,12 @@ void ExternalTextureTransform::Run(CloneContext& ctx,
auto* externalTextureParam = ctx.Clone(call_expr->args[0]);
ast::ExpressionList params;
if (intrinsic->Type() == sem::IntrinsicType::kTextureLoad) {
if (builtin->Type() == sem::BuiltinType::kTextureLoad) {
auto* coordsParam = ctx.Clone(call_expr->args[1]);
auto* levelParam = ctx.dst->Expr(0);
params = {externalTextureParam, coordsParam, levelParam};
} else if (intrinsic->Type() ==
sem::IntrinsicType::kTextureSampleLevel) {
} else if (builtin->Type() ==
sem::BuiltinType::kTextureSampleLevel) {
auto* samplerParam = ctx.Clone(call_expr->args[1]);
auto* coordsParam = ctx.Clone(call_expr->args[2]);
auto* levelParam = ctx.dst->Expr(0.0f);

View File

@ -148,11 +148,11 @@ struct MultiplanarExternalTexture::State {
// textureLoadExternal and textureSampleExternal calls.
ctx.ReplaceAll(
[&](const ast::CallExpression* expr) -> const ast::CallExpression* {
auto* intrinsic = sem.Get(expr)->Target()->As<sem::Intrinsic>();
auto* builtin = sem.Get(expr)->Target()->As<sem::Builtin>();
if (intrinsic && !intrinsic->Parameters().empty() &&
intrinsic->Parameters()[0]->Type()->Is<sem::ExternalTexture>() &&
intrinsic->Type() != sem::IntrinsicType::kTextureDimensions) {
if (builtin && !builtin->Parameters().empty() &&
builtin->Parameters()[0]->Type()->Is<sem::ExternalTexture>() &&
builtin->Type() != sem::BuiltinType::kTextureDimensions) {
auto it = new_binding_symbols.find(
expr->args[0]->As<ast::IdentifierExpression>()->symbol);
if (it == new_binding_symbols.end()) {
@ -164,11 +164,11 @@ struct MultiplanarExternalTexture::State {
}
auto& syms = it->second;
if (intrinsic->Type() == sem::IntrinsicType::kTextureLoad) {
if (builtin->Type() == sem::BuiltinType::kTextureLoad) {
return createTexLdExt(expr, syms);
}
if (intrinsic->Type() == sem::IntrinsicType::kTextureSampleLevel) {
if (builtin->Type() == sem::BuiltinType::kTextureSampleLevel) {
return createTexSmpExt(expr, syms);
}
@ -248,12 +248,12 @@ struct MultiplanarExternalTexture::State {
/// bodies of the textureSampleExternal and textureLoadExternal functions.
/// @param call_type determines which function body to generate
/// @returns a statement list that makes of the body of the chosen function
ast::StatementList createTexFnExtStatementList(sem::IntrinsicType call_type) {
ast::StatementList createTexFnExtStatementList(sem::BuiltinType call_type) {
using f32 = ProgramBuilder::f32;
const ast::CallExpression* single_plane_call = nullptr;
const ast::CallExpression* plane_0_call = nullptr;
const ast::CallExpression* plane_1_call = nullptr;
if (call_type == sem::IntrinsicType::kTextureSampleLevel) {
if (call_type == sem::BuiltinType::kTextureSampleLevel) {
// textureSampleLevel(plane0, smp, coord.xy, 0.0);
single_plane_call =
b.Call("textureSampleLevel", "plane0", "smp", "coord", 0.0f);
@ -263,7 +263,7 @@ struct MultiplanarExternalTexture::State {
// textureSampleLevel(plane1, smp, coord.xy, 0.0);
plane_1_call =
b.Call("textureSampleLevel", "plane1", "smp", "coord", 0.0f);
} else if (call_type == sem::IntrinsicType::kTextureLoad) {
} else if (call_type == sem::BuiltinType::kTextureLoad) {
// textureLoad(plane0, coords.xy, 0);
single_plane_call = b.Call("textureLoad", "plane0", "coord", 0);
// textureLoad(plane0, coords.xy, 0);
@ -272,7 +272,7 @@ struct MultiplanarExternalTexture::State {
plane_1_call = b.Call("textureLoad", "plane1", "coord", 0);
} else {
TINT_ICE(Transform, b.Diagnostics())
<< "unhandled intrinsic: " << call_type;
<< "unhandled builtin: " << call_type;
}
return {
@ -343,7 +343,7 @@ struct MultiplanarExternalTexture::State {
b.Param("params", b.ty.type_name(params_struct_sym))};
ast::StatementList statementList =
createTexFnExtStatementList(sem::IntrinsicType::kTextureSampleLevel);
createTexFnExtStatementList(sem::BuiltinType::kTextureSampleLevel);
b.Func(texture_sample_external_sym, varList, b.ty.vec4(b.ty.f32()),
statementList, {});
@ -386,7 +386,7 @@ struct MultiplanarExternalTexture::State {
b.Param("params", b.ty.type_name(params_struct_sym))};
ast::StatementList statement_list =
createTexFnExtStatementList(sem::IntrinsicType::kTextureLoad);
createTexFnExtStatementList(sem::BuiltinType::kTextureLoad);
b.Func(texture_load_external_sym, var_list, b.ty.vec4(b.ty.f32()),
statement_list, {});

View File

@ -20,7 +20,7 @@
#include "src/ast/struct_member.h"
#include "src/sem/binding_point.h"
#include "src/sem/intrinsic_type.h"
#include "src/sem/builtin_type.h"
#include "src/transform/transform.h"
namespace tint {

View File

@ -89,12 +89,12 @@ void RemovePhonies::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
if (!ast::TraverseExpressions(
stmt->rhs, ctx.dst->Diagnostics(),
[&](const ast::CallExpression* call) {
// ast::CallExpression may map to a function or intrinsic call
// 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::Intrinsic>()) {
->IsAnyOf<sem::Function, sem::Builtin>()) {
side_effects.push_back(call);
return ast::TraverseAction::Skip;
}

View File

@ -1257,7 +1257,7 @@ Output Renamer::Run(const Program* in, const DataMap& inputs) const {
// Disable auto-cloning of symbols, since we want to rename them.
CloneContext ctx(&out, in, false);
// Swizzles, intrinsic calls and builtin structure members need to keep their
// Swizzles, builtin calls and builtin structure members need to keep their
// symbols preserved.
std::unordered_set<const ast::IdentifierExpression*> preserve;
for (auto* node : in->ASTNodes().Objects()) {
@ -1284,7 +1284,7 @@ Output Renamer::Run(const Program* in, const DataMap& inputs) const {
<< "CallExpression has no semantic info";
continue;
}
if (sem->Target()->Is<sem::Intrinsic>()) {
if (sem->Target()->Is<sem::Builtin>()) {
preserve.emplace(call->target.name);
}
}

View File

@ -118,7 +118,7 @@ fn tint_symbol() -> @builtin(position) vec4<f32> {
EXPECT_THAT(data->remappings, ContainerEq(expected_remappings));
}
TEST_F(RenamerTest, PreserveIntrinsics) {
TEST_F(RenamerTest, PreserveBuiltins) {
auto* src = R"(
@stage(vertex)
fn entry() -> @builtin(position) vec4<f32> {
@ -666,20 +666,20 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
"VPOS",
"VertexShader",
"abort",
// "abs", // WGSL intrinsic
// "acos", // WGSL intrinsic
// "all", // WGSL intrinsic
// "abs", // WGSL builtin
// "acos", // WGSL builtin
// "all", // WGSL builtin
"allow_uav_condition",
// "any", // WGSL intrinsic
// "any", // WGSL builtin
"asdouble",
"asfloat",
// "asin", // WGSL intrinsic
// "asin", // WGSL builtin
"asint",
// "asm", // WGSL keyword
"asm_fragment",
"asuint",
// "atan", // WGSL intrinsic
// "atan2", // WGSL intrinsic
// "atan", // WGSL builtin
// "atan2", // WGSL builtin
"auto",
// "bool", // WGSL keyword
"bool1",
@ -704,14 +704,14 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
"bool4x4",
"branch",
// "break", // WGSL keyword
// "call", // WGSL intrinsic
// "call", // WGSL builtin
// "case", // WGSL keyword
"catch",
"cbuffer",
// "ceil", // WGSL intrinsic
// "ceil", // WGSL builtin
"centroid",
"char",
// "clamp", // WGSL intrinsic
// "clamp", // WGSL builtin
"class",
"clip",
"column_major",
@ -720,10 +720,10 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
// "const", // WGSL keyword
"const_cast",
// "continue", // WGSL keyword
// "cos", // WGSL intrinsic
// "cosh", // WGSL intrinsic
// "cos", // WGSL builtin
// "cosh", // WGSL builtin
"countbits",
// "cross", // WGSL intrinsic
// "cross", // WGSL builtin
"ddx",
"ddx_coarse",
"ddx_fine",
@ -733,11 +733,11 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
// "default", // WGSL keyword
"degrees",
"delete",
// "determinant", // WGSL intrinsic
// "determinant", // WGSL builtin
// "discard", // WGSL keyword
// "distance", // WGSL intrinsic
// "distance", // WGSL builtin
// "do", // WGSL keyword
// "dot", // WGSL intrinsic
// "dot", // WGSL builtin
"double",
"double1",
"double1x1",
@ -785,14 +785,14 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
// "else", // WGSL keyword
// "enum", // WGSL keyword
"errorf",
// "exp", // WGSL intrinsic
// "exp2", // WGSL intrinsic
// "exp", // WGSL builtin
// "exp2", // WGSL builtin
"explicit",
"export",
"extern",
"f16to32",
"f32tof16",
// "faceforward", // WGSL intrinsic
// "faceforward", // WGSL builtin
// "false", // WGSL keyword
"fastopt",
"firstbithigh",
@ -819,15 +819,15 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
"float4x2",
"float4x3",
"float4x4",
// "floor", // WGSL intrinsic
// "fma", // WGSL intrinsic
// "floor", // WGSL builtin
// "fma", // WGSL builtin
"fmod",
// "for", // WGSL keyword
"forcecase",
"frac",
// "frexp", // WGSL intrinsic
// "frexp", // WGSL builtin
"friend",
// "fwidth", // WGSL intrinsic
// "fwidth", // WGSL builtin
"fxgroup",
"goto",
"groupshared",
@ -881,22 +881,22 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
"isfinite",
"isinf",
"isnan",
// "ldexp", // WGSL intrinsic
// "length", // WGSL intrinsic
// "ldexp", // WGSL builtin
// "length", // WGSL builtin
"lerp",
"line",
"lineadj",
"linear",
"lit",
// "log", // WGSL intrinsic
// "log", // WGSL builtin
"log10",
// "log2", // WGSL intrinsic
// "log2", // WGSL builtin
"long",
// "loop", // WGSL keyword
"mad",
"matrix",
// "max", // WGSL intrinsic
// "min", // WGSL intrinsic
// "max", // WGSL builtin
// "min", // WGSL builtin
"min10float",
"min10float1",
"min10float1x1",
@ -1002,7 +1002,7 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
"min16uint4x2",
"min16uint4x3",
"min16uint4x4",
// "modf", // WGSL intrinsic
// "modf", // WGSL builtin
"msad4",
"mul",
"mutable",
@ -1011,7 +1011,7 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
"nointerpolation",
"noise",
"noperspective",
// "normalize", // WGSL intrinsic
// "normalize", // WGSL builtin
"numthreads",
"operator",
// "out", // WGSL keyword
@ -1020,7 +1020,7 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
"pixelfragment",
"pixelshader",
"point",
// "pow", // WGSL intrinsic
// "pow", // WGSL builtin
"precise",
"printf",
// "private", // WGSL keyword
@ -1028,13 +1028,13 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
"public",
"radians",
"rcp",
// "reflect", // WGSL intrinsic
// "reflect", // WGSL builtin
"refract",
"register",
"reinterpret_cast",
// "return", // WGSL keyword
// "reversebits", // WGSL intrinsic
// "round", // WGSL intrinsic
// "reversebits", // WGSL builtin
// "round", // WGSL builtin
"row_major",
"rsqrt",
"sample",
@ -1046,25 +1046,25 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
"saturate",
"shared",
"short",
// "sign", // WGSL intrinsic
// "sign", // WGSL builtin
"signed",
// "sin", // WGSL intrinsic
// "sin", // WGSL builtin
"sincos",
// "sinh", // WGSL intrinsic
// "sinh", // WGSL builtin
"sizeof",
// "smoothstep", // WGSL intrinsic
// "smoothstep", // WGSL builtin
"snorm",
// "sqrt", // WGSL intrinsic
// "sqrt", // WGSL builtin
"stateblock",
"stateblock_state",
"static",
"static_cast",
// "step", // WGSL intrinsic
// "step", // WGSL builtin
"string",
// "struct", // WGSL keyword
// "switch", // WGSL keyword
// "tan", // WGSL intrinsic
// "tanh", // WGSL intrinsic
// "tan", // WGSL builtin
// "tanh", // WGSL builtin
"tbuffer",
"technique",
"technique10",
@ -1106,7 +1106,7 @@ INSTANTIATE_TEST_SUITE_P(RenamerTestHlsl,
"triangle",
"triangleadj",
// "true", // WGSL keyword
// "trunc", // WGSL intrinsic
// "trunc", // WGSL builtin
"try",
// "typedef", // WGSL keyword
"typename",

View File

@ -200,24 +200,24 @@ struct Robustness::State {
return b.IndexAccessor(src, obj, idx.expr);
}
/// @param type intrinsic type
/// @returns true if the given intrinsic is a texture function that requires
/// @param type builtin type
/// @returns true if the given builtin is a texture function that requires
/// argument clamping,
bool TextureIntrinsicNeedsClamping(sem::IntrinsicType type) {
return type == sem::IntrinsicType::kTextureLoad ||
type == sem::IntrinsicType::kTextureStore;
bool TextureBuiltinNeedsClamping(sem::BuiltinType type) {
return type == sem::BuiltinType::kTextureLoad ||
type == sem::BuiltinType::kTextureStore;
}
/// Apply bounds clamping to the coordinates, array index and level arguments
/// of the `textureLoad()` and `textureStore()` intrinsics.
/// @param expr the intrinsic call expression
/// of the `textureLoad()` and `textureStore()` builtins.
/// @param expr the builtin call expression
/// @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_target = call->Target();
auto* intrinsic = call_target->As<sem::Intrinsic>();
if (!intrinsic || !TextureIntrinsicNeedsClamping(intrinsic->Type())) {
auto* builtin = call_target->As<sem::Builtin>();
if (!builtin || !TextureBuiltinNeedsClamping(builtin->Type())) {
return nullptr; // No transform, just clone.
}
@ -225,7 +225,7 @@ struct Robustness::State {
// Indices of the mandatory texture and coords parameters, and the optional
// array and level parameters.
auto& signature = intrinsic->Signature();
auto& signature = builtin->Signature();
auto texture_idx = signature.IndexOf(sem::ParameterUsage::kTexture);
auto coords_idx = signature.IndexOf(sem::ParameterUsage::kCoords);
auto array_idx = signature.IndexOf(sem::ParameterUsage::kArrayIndex);
@ -233,7 +233,7 @@ struct Robustness::State {
auto* texture_arg = expr->args[texture_idx];
auto* coords_arg = expr->args[coords_idx];
auto* coords_ty = intrinsic->Parameters()[coords_idx]->Type();
auto* coords_ty = builtin->Parameters()[coords_idx]->Type();
// If the level is provided, then we need to clamp this. As the level is
// used by textureDimensions() and the texture[Load|Store]() calls, we need

View File

@ -444,8 +444,8 @@ bool GeneratorImpl::EmitCall(std::ostream& out,
if (auto* func = target->As<sem::Function>()) {
return EmitFunctionCall(out, call, func);
}
if (auto* intrinsic = target->As<sem::Intrinsic>()) {
return EmitIntrinsicCall(out, call, intrinsic);
if (auto* builtin = target->As<sem::Builtin>()) {
return EmitBuiltinCall(out, call, builtin);
}
if (auto* cast = target->As<sem::TypeConversion>()) {
return EmitTypeConversion(out, call, cast);
@ -501,47 +501,47 @@ bool GeneratorImpl::EmitFunctionCall(std::ostream& out,
return true;
}
bool GeneratorImpl::EmitIntrinsicCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic) {
bool GeneratorImpl::EmitBuiltinCall(std::ostream& out,
const sem::Call* call,
const sem::Builtin* builtin) {
auto* expr = call->Declaration();
if (intrinsic->IsTexture()) {
return EmitTextureCall(out, call, intrinsic);
if (builtin->IsTexture()) {
return EmitTextureCall(out, call, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kSelect) {
if (builtin->Type() == sem::BuiltinType::kSelect) {
return EmitSelectCall(out, expr);
}
if (intrinsic->Type() == sem::IntrinsicType::kDot) {
return EmitDotCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kDot) {
return EmitDotCall(out, expr, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kModf) {
return EmitModfCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kModf) {
return EmitModfCall(out, expr, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kFrexp) {
return EmitFrexpCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kFrexp) {
return EmitFrexpCall(out, expr, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kIsNormal) {
return EmitIsNormalCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kIsNormal) {
return EmitIsNormalCall(out, expr, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kDegrees) {
return EmitDegreesCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kDegrees) {
return EmitDegreesCall(out, expr, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kRadians) {
return EmitRadiansCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kRadians) {
return EmitRadiansCall(out, expr, builtin);
}
if (intrinsic->IsDataPacking()) {
return EmitDataPackingCall(out, expr, intrinsic);
if (builtin->IsDataPacking()) {
return EmitDataPackingCall(out, expr, builtin);
}
if (intrinsic->IsDataUnpacking()) {
return EmitDataUnpackingCall(out, expr, intrinsic);
if (builtin->IsDataUnpacking()) {
return EmitDataUnpackingCall(out, expr, builtin);
}
if (intrinsic->IsBarrier()) {
return EmitBarrierCall(out, intrinsic);
if (builtin->IsBarrier()) {
return EmitBarrierCall(out, builtin);
}
if (intrinsic->IsAtomic()) {
return EmitWorkgroupAtomicCall(out, expr, intrinsic);
if (builtin->IsAtomic()) {
return EmitWorkgroupAtomicCall(out, expr, builtin);
}
auto name = generate_builtin_name(intrinsic);
auto name = generate_builtin_name(builtin);
if (name.empty()) {
return false;
}
@ -621,7 +621,7 @@ bool GeneratorImpl::EmitTypeConstructor(std::ostream& out,
bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
const sem::Builtin* builtin) {
auto call = [&](const char* name) {
out << name;
{
@ -639,8 +639,8 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
return true;
};
switch (intrinsic->Type()) {
case sem::IntrinsicType::kAtomicLoad: {
switch (builtin->Type()) {
case sem::BuiltinType::kAtomicLoad: {
// GLSL does not have an atomicLoad, so we emulate it with
// atomicOr using 0 as the OR value
out << "atomicOr";
@ -650,19 +650,19 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
return false;
}
out << ", 0";
if (intrinsic->ReturnType()->Is<sem::U32>()) {
if (builtin->ReturnType()->Is<sem::U32>()) {
out << "u";
}
}
return true;
}
case sem::IntrinsicType::kAtomicCompareExchangeWeak: {
return CallIntrinsicHelper(
out, expr, intrinsic,
case sem::BuiltinType::kAtomicCompareExchangeWeak: {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
{
auto pre = line(b);
if (!EmitTypeAndName(pre, intrinsic->ReturnType(),
if (!EmitTypeAndName(pre, builtin->ReturnType(),
ast::StorageClass::kNone,
ast::Access::kUndefined, "result")) {
return false;
@ -694,27 +694,27 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
});
}
case sem::IntrinsicType::kAtomicAdd:
case sem::IntrinsicType::kAtomicSub:
case sem::BuiltinType::kAtomicAdd:
case sem::BuiltinType::kAtomicSub:
return call("atomicAdd");
case sem::IntrinsicType::kAtomicMax:
case sem::BuiltinType::kAtomicMax:
return call("atomicMax");
case sem::IntrinsicType::kAtomicMin:
case sem::BuiltinType::kAtomicMin:
return call("atomicMin");
case sem::IntrinsicType::kAtomicAnd:
case sem::BuiltinType::kAtomicAnd:
return call("atomicAnd");
case sem::IntrinsicType::kAtomicOr:
case sem::BuiltinType::kAtomicOr:
return call("atomicOr");
case sem::IntrinsicType::kAtomicXor:
case sem::BuiltinType::kAtomicXor:
return call("atomicXor");
case sem::IntrinsicType::kAtomicExchange:
case sem::IntrinsicType::kAtomicStore:
case sem::BuiltinType::kAtomicExchange:
case sem::BuiltinType::kAtomicStore:
// GLSL does not have an atomicStore, so we emulate it with
// atomicExchange.
return call("atomicExchange");
@ -724,7 +724,7 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
}
TINT_UNREACHABLE(Writer, diagnostics_)
<< "unsupported atomic intrinsic: " << intrinsic->Type();
<< "unsupported atomic builtin: " << builtin->Type();
return false;
}
@ -755,8 +755,8 @@ bool GeneratorImpl::EmitSelectCall(std::ostream& out,
bool GeneratorImpl::EmitDotCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
auto* vec_ty = intrinsic->Parameters()[0]->Type()->As<sem::Vector>();
const sem::Builtin* builtin) {
auto* vec_ty = builtin->Parameters()[0]->Type()->As<sem::Vector>();
std::string fn = "dot";
if (vec_ty->type()->is_integer_scalar()) {
// GLSL does not have a builtin for dot() with integer vector types.
@ -827,12 +827,12 @@ bool GeneratorImpl::EmitDotCall(std::ostream& out,
bool GeneratorImpl::EmitModfCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
const sem::Builtin* builtin) {
if (expr->args.size() == 1) {
return CallIntrinsicHelper(
out, expr, intrinsic,
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
auto* ty = intrinsic->Parameters()[0]->Type();
auto* ty = builtin->Parameters()[0]->Type();
auto in = params[0];
std::string width;
@ -843,7 +843,7 @@ bool GeneratorImpl::EmitModfCall(std::ostream& out,
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
if (!EmitStructType(&helpers_,
intrinsic->ReturnType()->As<sem::Struct>())) {
builtin->ReturnType()->As<sem::Struct>())) {
return false;
}
@ -851,7 +851,7 @@ bool GeneratorImpl::EmitModfCall(std::ostream& out,
line(b) << "float" << width << " fract = modf(" << in << ", whole);";
{
auto l = line(b);
if (!EmitType(l, intrinsic->ReturnType(), ast::StorageClass::kNone,
if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
ast::Access::kUndefined, "")) {
return false;
}
@ -877,12 +877,12 @@ bool GeneratorImpl::EmitModfCall(std::ostream& out,
bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
const sem::Builtin* builtin) {
if (expr->args.size() == 1) {
return CallIntrinsicHelper(
out, expr, intrinsic,
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
auto* ty = intrinsic->Parameters()[0]->Type();
auto* ty = builtin->Parameters()[0]->Type();
auto in = params[0];
std::string width;
@ -893,7 +893,7 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
if (!EmitStructType(&helpers_,
intrinsic->ReturnType()->As<sem::Struct>())) {
builtin->ReturnType()->As<sem::Struct>())) {
return false;
}
@ -901,7 +901,7 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
line(b) << "float" << width << " sig = frexp(" << in << ", exp);";
{
auto l = line(b);
if (!EmitType(l, intrinsic->ReturnType(), ast::StorageClass::kNone,
if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
ast::Access::kUndefined, "")) {
return false;
}
@ -914,12 +914,12 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
// DEPRECATED
// Exponent is an integer in WGSL, but HLSL wants a float.
// We need to make the call with a temporary float, and then cast.
return CallIntrinsicHelper(
out, expr, intrinsic,
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
auto* significand_ty = intrinsic->Parameters()[0]->Type();
auto* significand_ty = builtin->Parameters()[0]->Type();
auto significand = params[0];
auto* exponent_ty = intrinsic->Parameters()[1]->Type();
auto* exponent_ty = builtin->Parameters()[1]->Type();
auto exponent = params[1];
std::string width;
@ -948,12 +948,12 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
bool GeneratorImpl::EmitIsNormalCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
// GLSL doesn't have a isNormal intrinsic, we need to emulate
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
// GLSL doesn't have a isNormal builtin, we need to emulate
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
auto* input_ty = intrinsic->Parameters()[0]->Type();
auto* input_ty = builtin->Parameters()[0]->Type();
std::string width;
if (auto* vec = input_ty->As<sem::Vector>()) {
@ -976,9 +976,9 @@ bool GeneratorImpl::EmitIsNormalCall(std::ostream& out,
bool GeneratorImpl::EmitDegreesCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
line(b) << "return " << params[0] << " * " << std::setprecision(20)
<< sem::kRadToDeg << ";";
@ -988,9 +988,9 @@ bool GeneratorImpl::EmitDegreesCall(std::ostream& out,
bool GeneratorImpl::EmitRadiansCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
line(b) << "return " << params[0] << " * " << std::setprecision(20)
<< sem::kDegToRad << ";";
@ -1000,28 +1000,28 @@ bool GeneratorImpl::EmitRadiansCall(std::ostream& out,
bool GeneratorImpl::EmitDataPackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
uint32_t dims = 2;
bool is_signed = false;
uint32_t scale = 65535;
if (intrinsic->Type() == sem::IntrinsicType::kPack4x8snorm ||
intrinsic->Type() == sem::IntrinsicType::kPack4x8unorm) {
if (builtin->Type() == sem::BuiltinType::kPack4x8snorm ||
builtin->Type() == sem::BuiltinType::kPack4x8unorm) {
dims = 4;
scale = 255;
}
if (intrinsic->Type() == sem::IntrinsicType::kPack4x8snorm ||
intrinsic->Type() == sem::IntrinsicType::kPack2x16snorm) {
if (builtin->Type() == sem::BuiltinType::kPack4x8snorm ||
builtin->Type() == sem::BuiltinType::kPack2x16snorm) {
is_signed = true;
scale = (scale - 1) / 2;
}
switch (intrinsic->Type()) {
case sem::IntrinsicType::kPack4x8snorm:
case sem::IntrinsicType::kPack4x8unorm:
case sem::IntrinsicType::kPack2x16snorm:
case sem::IntrinsicType::kPack2x16unorm: {
switch (builtin->Type()) {
case sem::BuiltinType::kPack4x8snorm:
case sem::BuiltinType::kPack4x8unorm:
case sem::BuiltinType::kPack2x16snorm:
case sem::BuiltinType::kPack2x16unorm: {
{
auto l = line(b);
l << (is_signed ? "" : "u") << "int" << dims
@ -1048,7 +1048,7 @@ bool GeneratorImpl::EmitDataPackingCall(std::ostream& out,
}
break;
}
case sem::IntrinsicType::kPack2x16float: {
case sem::BuiltinType::kPack2x16float: {
line(b) << "uint2 i = f32tof16(" << params[0] << ");";
line(b) << "return i.x | (i.y << 16);";
break;
@ -1056,7 +1056,7 @@ bool GeneratorImpl::EmitDataPackingCall(std::ostream& out,
default:
diagnostics_.add_error(
diag::System::Writer,
"Internal error: unhandled data packing intrinsic");
"Internal error: unhandled data packing builtin");
return false;
}
@ -1066,26 +1066,26 @@ bool GeneratorImpl::EmitDataPackingCall(std::ostream& out,
bool GeneratorImpl::EmitDataUnpackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
uint32_t dims = 2;
bool is_signed = false;
uint32_t scale = 65535;
if (intrinsic->Type() == sem::IntrinsicType::kUnpack4x8snorm ||
intrinsic->Type() == sem::IntrinsicType::kUnpack4x8unorm) {
if (builtin->Type() == sem::BuiltinType::kUnpack4x8snorm ||
builtin->Type() == sem::BuiltinType::kUnpack4x8unorm) {
dims = 4;
scale = 255;
}
if (intrinsic->Type() == sem::IntrinsicType::kUnpack4x8snorm ||
intrinsic->Type() == sem::IntrinsicType::kUnpack2x16snorm) {
if (builtin->Type() == sem::BuiltinType::kUnpack4x8snorm ||
builtin->Type() == sem::BuiltinType::kUnpack2x16snorm) {
is_signed = true;
scale = (scale - 1) / 2;
}
switch (intrinsic->Type()) {
case sem::IntrinsicType::kUnpack4x8snorm:
case sem::IntrinsicType::kUnpack2x16snorm: {
switch (builtin->Type()) {
case sem::BuiltinType::kUnpack4x8snorm:
case sem::BuiltinType::kUnpack2x16snorm: {
line(b) << "int j = int(" << params[0] << ");";
{ // Perform sign extension on the converted values.
auto l = line(b);
@ -1101,8 +1101,8 @@ bool GeneratorImpl::EmitDataUnpackingCall(std::ostream& out,
<< ".0, " << (is_signed ? "-1.0" : "0.0") << ", 1.0);";
break;
}
case sem::IntrinsicType::kUnpack4x8unorm:
case sem::IntrinsicType::kUnpack2x16unorm: {
case sem::BuiltinType::kUnpack4x8unorm:
case sem::BuiltinType::kUnpack2x16unorm: {
line(b) << "uint j = " << params[0] << ";";
{
auto l = line(b);
@ -1119,14 +1119,14 @@ bool GeneratorImpl::EmitDataUnpackingCall(std::ostream& out,
line(b) << "return float" << dims << "(i) / " << scale << ".0;";
break;
}
case sem::IntrinsicType::kUnpack2x16float:
case sem::BuiltinType::kUnpack2x16float:
line(b) << "uint i = " << params[0] << ";";
line(b) << "return f16tof32(uint2(i & 0xffff, i >> 16));";
break;
default:
diagnostics_.add_error(
diag::System::Writer,
"Internal error: unhandled data packing intrinsic");
"Internal error: unhandled data packing builtin");
return false;
}
@ -1135,16 +1135,16 @@ bool GeneratorImpl::EmitDataUnpackingCall(std::ostream& out,
}
bool GeneratorImpl::EmitBarrierCall(std::ostream& out,
const sem::Intrinsic* intrinsic) {
const sem::Builtin* builtin) {
// TODO(crbug.com/tint/661): Combine sequential barriers to a single
// instruction.
if (intrinsic->Type() == sem::IntrinsicType::kWorkgroupBarrier) {
if (builtin->Type() == sem::BuiltinType::kWorkgroupBarrier) {
out << "memoryBarrierShared()";
} else if (intrinsic->Type() == sem::IntrinsicType::kStorageBarrier) {
} else if (builtin->Type() == sem::BuiltinType::kStorageBarrier) {
out << "memoryBarrierBuffer()";
} else {
TINT_UNREACHABLE(Writer, diagnostics_)
<< "unexpected barrier intrinsic type " << sem::str(intrinsic->Type());
<< "unexpected barrier builtin type " << sem::str(builtin->Type());
return false;
}
return true;
@ -1152,10 +1152,10 @@ bool GeneratorImpl::EmitBarrierCall(std::ostream& out,
bool GeneratorImpl::EmitTextureCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic) {
const sem::Builtin* builtin) {
using Usage = sem::ParameterUsage;
auto& signature = intrinsic->Signature();
auto& signature = builtin->Signature();
auto* expr = call->Declaration();
auto arguments = expr->args;
@ -1173,8 +1173,8 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
auto* texture_type = TypeOf(texture)->UnwrapRef()->As<sem::Texture>();
switch (intrinsic->Type()) {
case sem::IntrinsicType::kTextureDimensions: {
switch (builtin->Type()) {
case sem::BuiltinType::kTextureDimensions: {
if (texture_type->Is<sem::StorageTexture>()) {
out << "imageSize(";
} else {
@ -1207,8 +1207,8 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
return true;
}
// TODO(senorblanco): determine if this works for array textures
case sem::IntrinsicType::kTextureNumLayers:
case sem::IntrinsicType::kTextureNumLevels: {
case sem::BuiltinType::kTextureNumLayers:
case sem::BuiltinType::kTextureNumLevels: {
out << "textureQueryLevels(";
if (!EmitExpression(out, texture)) {
return false;
@ -1216,7 +1216,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
out << ");";
return true;
}
case sem::IntrinsicType::kTextureNumSamples: {
case sem::BuiltinType::kTextureNumSamples: {
out << "textureSamples(";
if (!EmitExpression(out, texture)) {
return false;
@ -1231,44 +1231,44 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
uint32_t glsl_ret_width = 4u;
bool is_depth = texture_type->Is<sem::DepthTexture>();
switch (intrinsic->Type()) {
case sem::IntrinsicType::kTextureSample:
case sem::IntrinsicType::kTextureSampleBias:
switch (builtin->Type()) {
case sem::BuiltinType::kTextureSample:
case sem::BuiltinType::kTextureSampleBias:
out << "texture";
if (is_depth) {
glsl_ret_width = 1u;
}
break;
case sem::IntrinsicType::kTextureSampleLevel:
case sem::BuiltinType::kTextureSampleLevel:
out << "textureLod";
break;
case sem::IntrinsicType::kTextureGather:
case sem::IntrinsicType::kTextureGatherCompare:
case sem::BuiltinType::kTextureGather:
case sem::BuiltinType::kTextureGatherCompare:
out << "textureGather";
break;
case sem::IntrinsicType::kTextureSampleGrad:
case sem::BuiltinType::kTextureSampleGrad:
out << "textureGrad";
break;
case sem::IntrinsicType::kTextureSampleCompare:
case sem::IntrinsicType::kTextureSampleCompareLevel:
case sem::BuiltinType::kTextureSampleCompare:
case sem::BuiltinType::kTextureSampleCompareLevel:
out << "texture";
glsl_ret_width = 1;
break;
case sem::IntrinsicType::kTextureLoad:
case sem::BuiltinType::kTextureLoad:
out << "texelFetch";
break;
case sem::IntrinsicType::kTextureStore:
case sem::BuiltinType::kTextureStore:
out << "imageStore";
break;
default:
diagnostics_.add_error(
diag::System::Writer,
"Internal compiler error: Unhandled texture intrinsic '" +
std::string(intrinsic->str()) + "'");
"Internal compiler error: Unhandled texture builtin '" +
std::string(builtin->str()) + "'");
return false;
}
if (intrinsic->Signature().IndexOf(sem::ParameterUsage::kOffset) >= 0) {
if (builtin->Signature().IndexOf(sem::ParameterUsage::kOffset) >= 0) {
out << "Offset";
}
@ -1299,7 +1299,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
if (auto* depth_ref = arg(Usage::kDepthRef)) {
param_coords =
AppendVector(&builder_, param_coords, depth_ref)->Declaration();
} else if (intrinsic->Type() == sem::IntrinsicType::kTextureSample) {
} else if (builtin->Type() == sem::BuiltinType::kTextureSample) {
// Sampling a depth texture in GLSL always requires a depth reference, so
// append zero here.
auto* f32 = builder_.create<sem::F32>();
@ -1327,7 +1327,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
}
// GLSL's textureGather always requires a refZ parameter.
if (is_depth && intrinsic->Type() == sem::IntrinsicType::kTextureGather) {
if (is_depth && builtin->Type() == sem::BuiltinType::kTextureGather) {
out << ", 0.0";
}
@ -1347,21 +1347,21 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
if (!EmitExpression(out, e)) {
return false;
}
} else if (intrinsic->Type() == sem::IntrinsicType::kTextureSample) {
} else if (builtin->Type() == sem::BuiltinType::kTextureSample) {
out << ", 0.0f";
}
}
out << ")";
if (intrinsic->ReturnType()->Is<sem::Void>()) {
if (builtin->ReturnType()->Is<sem::Void>()) {
return true;
}
// If the intrinsic return type does not match the number of elements of the
// GLSL intrinsic, we need to swizzle the expression to generate the correct
// If the builtin return type does not match the number of elements of the
// GLSL builtin, we need to swizzle the expression to generate the correct
// number of components.
uint32_t wgsl_ret_width = 1;
if (auto* vec = intrinsic->ReturnType()->As<sem::Vector>()) {
if (auto* vec = builtin->ReturnType()->As<sem::Vector>()) {
wgsl_ret_width = vec->Width();
}
if (wgsl_ret_width < glsl_ret_width) {
@ -1374,100 +1374,99 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
TINT_ICE(Writer, diagnostics_)
<< "WGSL return width (" << wgsl_ret_width
<< ") is wider than GLSL return width (" << glsl_ret_width << ") for "
<< intrinsic->Type();
<< builtin->Type();
return false;
}
return true;
}
std::string GeneratorImpl::generate_builtin_name(
const sem::Intrinsic* intrinsic) {
switch (intrinsic->Type()) {
case sem::IntrinsicType::kAbs:
case sem::IntrinsicType::kAcos:
case sem::IntrinsicType::kAll:
case sem::IntrinsicType::kAny:
case sem::IntrinsicType::kAsin:
case sem::IntrinsicType::kAtan:
case sem::IntrinsicType::kCeil:
case sem::IntrinsicType::kClamp:
case sem::IntrinsicType::kCos:
case sem::IntrinsicType::kCosh:
case sem::IntrinsicType::kCross:
case sem::IntrinsicType::kDeterminant:
case sem::IntrinsicType::kDistance:
case sem::IntrinsicType::kDot:
case sem::IntrinsicType::kExp:
case sem::IntrinsicType::kExp2:
case sem::IntrinsicType::kFloor:
case sem::IntrinsicType::kFrexp:
case sem::IntrinsicType::kLdexp:
case sem::IntrinsicType::kLength:
case sem::IntrinsicType::kLog:
case sem::IntrinsicType::kLog2:
case sem::IntrinsicType::kMax:
case sem::IntrinsicType::kMin:
case sem::IntrinsicType::kModf:
case sem::IntrinsicType::kNormalize:
case sem::IntrinsicType::kPow:
case sem::IntrinsicType::kReflect:
case sem::IntrinsicType::kRefract:
case sem::IntrinsicType::kRound:
case sem::IntrinsicType::kSign:
case sem::IntrinsicType::kSin:
case sem::IntrinsicType::kSinh:
case sem::IntrinsicType::kSqrt:
case sem::IntrinsicType::kStep:
case sem::IntrinsicType::kTan:
case sem::IntrinsicType::kTanh:
case sem::IntrinsicType::kTranspose:
case sem::IntrinsicType::kTrunc:
return intrinsic->str();
case sem::IntrinsicType::kAtan2:
std::string GeneratorImpl::generate_builtin_name(const sem::Builtin* builtin) {
switch (builtin->Type()) {
case sem::BuiltinType::kAbs:
case sem::BuiltinType::kAcos:
case sem::BuiltinType::kAll:
case sem::BuiltinType::kAny:
case sem::BuiltinType::kAsin:
case sem::BuiltinType::kAtan:
case sem::BuiltinType::kCeil:
case sem::BuiltinType::kClamp:
case sem::BuiltinType::kCos:
case sem::BuiltinType::kCosh:
case sem::BuiltinType::kCross:
case sem::BuiltinType::kDeterminant:
case sem::BuiltinType::kDistance:
case sem::BuiltinType::kDot:
case sem::BuiltinType::kExp:
case sem::BuiltinType::kExp2:
case sem::BuiltinType::kFloor:
case sem::BuiltinType::kFrexp:
case sem::BuiltinType::kLdexp:
case sem::BuiltinType::kLength:
case sem::BuiltinType::kLog:
case sem::BuiltinType::kLog2:
case sem::BuiltinType::kMax:
case sem::BuiltinType::kMin:
case sem::BuiltinType::kModf:
case sem::BuiltinType::kNormalize:
case sem::BuiltinType::kPow:
case sem::BuiltinType::kReflect:
case sem::BuiltinType::kRefract:
case sem::BuiltinType::kRound:
case sem::BuiltinType::kSign:
case sem::BuiltinType::kSin:
case sem::BuiltinType::kSinh:
case sem::BuiltinType::kSqrt:
case sem::BuiltinType::kStep:
case sem::BuiltinType::kTan:
case sem::BuiltinType::kTanh:
case sem::BuiltinType::kTranspose:
case sem::BuiltinType::kTrunc:
return builtin->str();
case sem::BuiltinType::kAtan2:
return "atan";
case sem::IntrinsicType::kCountOneBits:
case sem::BuiltinType::kCountOneBits:
return "countbits";
case sem::IntrinsicType::kDpdx:
case sem::BuiltinType::kDpdx:
return "ddx";
case sem::IntrinsicType::kDpdxCoarse:
case sem::BuiltinType::kDpdxCoarse:
return "ddx_coarse";
case sem::IntrinsicType::kDpdxFine:
case sem::BuiltinType::kDpdxFine:
return "ddx_fine";
case sem::IntrinsicType::kDpdy:
case sem::BuiltinType::kDpdy:
return "ddy";
case sem::IntrinsicType::kDpdyCoarse:
case sem::BuiltinType::kDpdyCoarse:
return "ddy_coarse";
case sem::IntrinsicType::kDpdyFine:
case sem::BuiltinType::kDpdyFine:
return "ddy_fine";
case sem::IntrinsicType::kFaceForward:
case sem::BuiltinType::kFaceForward:
return "faceforward";
case sem::IntrinsicType::kFract:
case sem::BuiltinType::kFract:
return "frac";
case sem::IntrinsicType::kFma:
case sem::BuiltinType::kFma:
return "mad";
case sem::IntrinsicType::kFwidth:
case sem::IntrinsicType::kFwidthCoarse:
case sem::IntrinsicType::kFwidthFine:
case sem::BuiltinType::kFwidth:
case sem::BuiltinType::kFwidthCoarse:
case sem::BuiltinType::kFwidthFine:
return "fwidth";
case sem::IntrinsicType::kInverseSqrt:
case sem::BuiltinType::kInverseSqrt:
return "rsqrt";
case sem::IntrinsicType::kIsFinite:
case sem::BuiltinType::kIsFinite:
return "isfinite";
case sem::IntrinsicType::kIsInf:
case sem::BuiltinType::kIsInf:
return "isinf";
case sem::IntrinsicType::kIsNan:
case sem::BuiltinType::kIsNan:
return "isnan";
case sem::IntrinsicType::kMix:
case sem::BuiltinType::kMix:
return "mix";
case sem::IntrinsicType::kReverseBits:
case sem::BuiltinType::kReverseBits:
return "reversebits";
case sem::IntrinsicType::kSmoothStep:
case sem::BuiltinType::kSmoothStep:
return "smoothstep";
default:
diagnostics_.add_error(
diag::System::Writer,
"Unknown builtin method: " + std::string(intrinsic->str()));
"Unknown builtin method: " + std::string(builtin->str()));
}
return "";
@ -2624,28 +2623,28 @@ bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
}
template <typename F>
bool GeneratorImpl::CallIntrinsicHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Intrinsic* intrinsic,
F&& build) {
bool GeneratorImpl::CallBuiltinHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Builtin* builtin,
F&& build) {
// Generate the helper function if it hasn't been created already
auto fn = utils::GetOrCreate(intrinsics_, intrinsic, [&]() -> std::string {
auto fn = utils::GetOrCreate(builtins_, builtin, [&]() -> std::string {
TextBuffer b;
TINT_DEFER(helpers_.Append(b));
auto fn_name =
UniqueIdentifier(std::string("tint_") + sem::str(intrinsic->Type()));
UniqueIdentifier(std::string("tint_") + sem::str(builtin->Type()));
std::vector<std::string> parameter_names;
{
auto decl = line(&b);
if (!EmitTypeAndName(decl, intrinsic->ReturnType(),
if (!EmitTypeAndName(decl, builtin->ReturnType(),
ast::StorageClass::kNone, ast::Access::kUndefined,
fn_name)) {
return "";
}
{
ScopedParen sp(decl);
for (auto* param : intrinsic->Parameters()) {
for (auto* param : builtin->Parameters()) {
if (!parameter_names.empty()) {
decl << ", ";
}

View File

@ -42,7 +42,7 @@ namespace tint {
// Forward declarations
namespace sem {
class Call;
class Intrinsic;
class Builtin;
class TypeConstructor;
class TypeConversion;
} // namespace sem
@ -116,14 +116,14 @@ class GeneratorImpl : public TextGenerator {
bool EmitFunctionCall(std::ostream& out,
const sem::Call* call,
const sem::Function* function);
/// Handles generating an intrinsic call expression
/// Handles generating a builtin call expression
/// @param out the output of the expression stream
/// @param call the call expression
/// @param intrinsic the intrinsic being called
/// @param builtin the builtin being called
/// @returns true if the expression is emitted
bool EmitIntrinsicCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic);
bool EmitBuiltinCall(std::ostream& out,
const sem::Call* call,
const sem::Builtin* builtin);
/// Handles generating a type conversion expression
/// @param out the output of the expression stream
/// @param call the call expression
@ -140,11 +140,11 @@ class GeneratorImpl : public TextGenerator {
bool EmitTypeConstructor(std::ostream& out,
const sem::Call* call,
const sem::TypeConstructor* ctor);
/// Handles generating a barrier intrinsic call
/// Handles generating a barrier builtin call
/// @param out the output of the expression stream
/// @param intrinsic the semantic information for the barrier intrinsic
/// @param builtin the semantic information for the barrier builtin
/// @returns true if the call expression is emitted
bool EmitBarrierCall(std::ostream& out, const sem::Intrinsic* intrinsic);
bool EmitBarrierCall(std::ostream& out, const sem::Builtin* builtin);
/// Handles generating an atomic intrinsic call for a storage buffer variable
/// @param out the output of the expression stream
/// @param expr the call expression
@ -154,92 +154,92 @@ class GeneratorImpl : public TextGenerator {
std::ostream& out,
const ast::CallExpression* expr,
const transform::DecomposeMemoryAccess::Intrinsic* intrinsic);
/// Handles generating an atomic intrinsic call for a workgroup variable
/// Handles generating an atomic builtin call for a workgroup variable
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the atomic intrinsic
/// @param builtin the semantic information for the atomic builtin
/// @returns true if the call expression is emitted
bool EmitWorkgroupAtomicCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
const sem::Builtin* builtin);
/// Handles generating a call to a texture function (`textureSample`,
/// `textureSampleGrad`, etc)
/// @param out the output of the expression stream
/// @param call the call expression
/// @param intrinsic the semantic information for the texture intrinsic
/// @param builtin the semantic information for the texture builtin
/// @returns true if the call expression is emitted
bool EmitTextureCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `select()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `select()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @returns true if the call expression is emitted
bool EmitSelectCall(std::ostream& out, const ast::CallExpression* expr);
/// Handles generating a call to the `dot()` intrinsic
/// Handles generating a call to the `dot()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitDotCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `modf()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `modf()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitModfCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `frexp()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `frexp()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitFrexpCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `isNormal()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `isNormal()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitIsNormalCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `degrees()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `degrees()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitDegreesCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `radians()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `radians()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitRadiansCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to data packing intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to data packing builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the texture intrinsic
/// @param builtin the semantic information for the texture builtin
/// @returns true if the call expression is emitted
bool EmitDataPackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to data unpacking intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to data unpacking builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the texture intrinsic
/// @param builtin the semantic information for the texture builtin
/// @returns true if the call expression is emitted
bool EmitDataUnpackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
const sem::Builtin* builtin);
/// Handles a case statement
/// @param stmt the statement
/// @returns true if the statement was emitted successfully
@ -407,9 +407,9 @@ class GeneratorImpl : public TextGenerator {
/// @returns true if the variable was emitted
bool EmitProgramConstVariable(const ast::Variable* var);
/// Handles generating a builtin method name
/// @param intrinsic the semantic info for the intrinsic
/// @param builtin the semantic info for the builtin
/// @returns the name or "" if not valid
std::string generate_builtin_name(const sem::Intrinsic* intrinsic);
std::string generate_builtin_name(const sem::Builtin* builtin);
/// Converts a builtin to a gl_ string
/// @param builtin the builtin to convert
/// @param stage pipeline stage in which this builtin is used
@ -444,13 +444,13 @@ class GeneratorImpl : public TextGenerator {
};
};
/// CallIntrinsicHelper will call the intrinsic helper function, creating it
/// if it hasn't been built already. If the intrinsic needs to be built then
/// CallIntrinsicHelper will generate the function signature and will call
/// CallBuiltinHelper will call the builtin helper function, creating it
/// if it hasn't been built already. If the builtin needs to be built then
/// CallBuiltinHelper will generate the function signature and will call
/// `build` to emit the body of the function.
/// @param out the output of the expression stream
/// @param call the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @param build a function with the signature:
/// `bool(TextBuffer* buffer, const std::vector<std::string>& params)`
/// Where:
@ -458,16 +458,16 @@ class GeneratorImpl : public TextGenerator {
/// `params` is the name of all the generated function parameters
/// @returns true if the call expression is emitted
template <typename F>
bool CallIntrinsicHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Intrinsic* intrinsic,
F&& build);
bool CallBuiltinHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Builtin* builtin,
F&& build);
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::Intrinsic*, std::string> intrinsics_;
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_;
std::unordered_map<const sem::Vector*, std::string> int_dot_funcs_;

View File

@ -23,11 +23,11 @@ namespace writer {
namespace glsl {
namespace {
using IntrinsicType = sem::IntrinsicType;
using BuiltinType = sem::BuiltinType;
using ::testing::HasSubstr;
using GlslGeneratorImplTest_Intrinsic = TestHelper;
using GlslGeneratorImplTest_Builtin = TestHelper;
enum class ParamType {
kF32,
@ -35,12 +35,12 @@ enum class ParamType {
kBool,
};
struct IntrinsicData {
IntrinsicType intrinsic;
struct BuiltinData {
BuiltinType builtin;
ParamType type;
const char* glsl_name;
};
inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
out << data.glsl_name;
switch (data.type) {
case ParamType::kF32:
@ -57,104 +57,104 @@ inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
return out;
}
const ast::CallExpression* GenerateCall(IntrinsicType intrinsic,
const ast::CallExpression* GenerateCall(BuiltinType builtin,
ParamType type,
ProgramBuilder* builder) {
std::string name;
std::ostringstream str(name);
str << intrinsic;
switch (intrinsic) {
case IntrinsicType::kAcos:
case IntrinsicType::kAsin:
case IntrinsicType::kAtan:
case IntrinsicType::kCeil:
case IntrinsicType::kCos:
case IntrinsicType::kCosh:
case IntrinsicType::kDpdx:
case IntrinsicType::kDpdxCoarse:
case IntrinsicType::kDpdxFine:
case IntrinsicType::kDpdy:
case IntrinsicType::kDpdyCoarse:
case IntrinsicType::kDpdyFine:
case IntrinsicType::kExp:
case IntrinsicType::kExp2:
case IntrinsicType::kFloor:
case IntrinsicType::kFract:
case IntrinsicType::kFwidth:
case IntrinsicType::kFwidthCoarse:
case IntrinsicType::kFwidthFine:
case IntrinsicType::kInverseSqrt:
case IntrinsicType::kIsFinite:
case IntrinsicType::kIsInf:
case IntrinsicType::kIsNan:
case IntrinsicType::kIsNormal:
case IntrinsicType::kLength:
case IntrinsicType::kLog:
case IntrinsicType::kLog2:
case IntrinsicType::kNormalize:
case IntrinsicType::kRound:
case IntrinsicType::kSin:
case IntrinsicType::kSinh:
case IntrinsicType::kSqrt:
case IntrinsicType::kTan:
case IntrinsicType::kTanh:
case IntrinsicType::kTrunc:
case IntrinsicType::kSign:
str << builtin;
switch (builtin) {
case BuiltinType::kAcos:
case BuiltinType::kAsin:
case BuiltinType::kAtan:
case BuiltinType::kCeil:
case BuiltinType::kCos:
case BuiltinType::kCosh:
case BuiltinType::kDpdx:
case BuiltinType::kDpdxCoarse:
case BuiltinType::kDpdxFine:
case BuiltinType::kDpdy:
case BuiltinType::kDpdyCoarse:
case BuiltinType::kDpdyFine:
case BuiltinType::kExp:
case BuiltinType::kExp2:
case BuiltinType::kFloor:
case BuiltinType::kFract:
case BuiltinType::kFwidth:
case BuiltinType::kFwidthCoarse:
case BuiltinType::kFwidthFine:
case BuiltinType::kInverseSqrt:
case BuiltinType::kIsFinite:
case BuiltinType::kIsInf:
case BuiltinType::kIsNan:
case BuiltinType::kIsNormal:
case BuiltinType::kLength:
case BuiltinType::kLog:
case BuiltinType::kLog2:
case BuiltinType::kNormalize:
case BuiltinType::kRound:
case BuiltinType::kSin:
case BuiltinType::kSinh:
case BuiltinType::kSqrt:
case BuiltinType::kTan:
case BuiltinType::kTanh:
case BuiltinType::kTrunc:
case BuiltinType::kSign:
return builder->Call(str.str(), "f2");
case IntrinsicType::kLdexp:
case BuiltinType::kLdexp:
return builder->Call(str.str(), "f2", "i2");
case IntrinsicType::kAtan2:
case IntrinsicType::kDot:
case IntrinsicType::kDistance:
case IntrinsicType::kPow:
case IntrinsicType::kReflect:
case IntrinsicType::kStep:
case BuiltinType::kAtan2:
case BuiltinType::kDot:
case BuiltinType::kDistance:
case BuiltinType::kPow:
case BuiltinType::kReflect:
case BuiltinType::kStep:
return builder->Call(str.str(), "f2", "f2");
case IntrinsicType::kCross:
case BuiltinType::kCross:
return builder->Call(str.str(), "f3", "f3");
case IntrinsicType::kFma:
case IntrinsicType::kMix:
case IntrinsicType::kFaceForward:
case IntrinsicType::kSmoothStep:
case BuiltinType::kFma:
case BuiltinType::kMix:
case BuiltinType::kFaceForward:
case BuiltinType::kSmoothStep:
return builder->Call(str.str(), "f2", "f2", "f2");
case IntrinsicType::kAll:
case IntrinsicType::kAny:
case BuiltinType::kAll:
case BuiltinType::kAny:
return builder->Call(str.str(), "b2");
case IntrinsicType::kAbs:
case BuiltinType::kAbs:
if (type == ParamType::kF32) {
return builder->Call(str.str(), "f2");
} else {
return builder->Call(str.str(), "u2");
}
case IntrinsicType::kCountOneBits:
case IntrinsicType::kReverseBits:
case BuiltinType::kCountOneBits:
case BuiltinType::kReverseBits:
return builder->Call(str.str(), "u2");
case IntrinsicType::kMax:
case IntrinsicType::kMin:
case BuiltinType::kMax:
case BuiltinType::kMin:
if (type == ParamType::kF32) {
return builder->Call(str.str(), "f2", "f2");
} else {
return builder->Call(str.str(), "u2", "u2");
}
case IntrinsicType::kClamp:
case BuiltinType::kClamp:
if (type == ParamType::kF32) {
return builder->Call(str.str(), "f2", "f2", "f2");
} else {
return builder->Call(str.str(), "u2", "u2", "u2");
}
case IntrinsicType::kSelect:
case BuiltinType::kSelect:
return builder->Call(str.str(), "f2", "f2", "b2");
case IntrinsicType::kDeterminant:
case BuiltinType::kDeterminant:
return builder->Call(str.str(), "m2x2");
case IntrinsicType::kTranspose:
case BuiltinType::kTranspose:
return builder->Call(str.str(), "m3x2");
default:
break;
}
return nullptr;
}
using GlslIntrinsicTest = TestParamHelper<IntrinsicData>;
TEST_P(GlslIntrinsicTest, Emit) {
using GlslBuiltinTest = TestParamHelper<BuiltinData>;
TEST_P(GlslBuiltinTest, Emit) {
auto param = GetParam();
Global("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
@ -165,8 +165,8 @@ TEST_P(GlslIntrinsicTest, Emit) {
Global("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
Global("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
auto* call = GenerateCall(param.intrinsic, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled intrinsic";
auto* call = GenerateCall(param.builtin, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled builtin";
Func("func", {}, ty.void_(), {CallStmt(call)},
{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
@ -176,89 +176,82 @@ TEST_P(GlslIntrinsicTest, Emit) {
ASSERT_NE(sem, nullptr);
auto* target = sem->Target();
ASSERT_NE(target, nullptr);
auto* intrinsic = target->As<sem::Intrinsic>();
ASSERT_NE(intrinsic, nullptr);
auto* builtin = target->As<sem::Builtin>();
ASSERT_NE(builtin, nullptr);
EXPECT_EQ(gen.generate_builtin_name(intrinsic), param.glsl_name);
EXPECT_EQ(gen.generate_builtin_name(builtin), param.glsl_name);
}
INSTANTIATE_TEST_SUITE_P(
GlslGeneratorImplTest_Intrinsic,
GlslIntrinsicTest,
GlslGeneratorImplTest_Builtin,
GlslBuiltinTest,
testing::Values(
IntrinsicData{IntrinsicType::kAbs, ParamType::kF32, "abs"},
IntrinsicData{IntrinsicType::kAbs, ParamType::kU32, "abs"},
IntrinsicData{IntrinsicType::kAcos, ParamType::kF32, "acos"},
IntrinsicData{IntrinsicType::kAll, ParamType::kBool, "all"},
IntrinsicData{IntrinsicType::kAny, ParamType::kBool, "any"},
IntrinsicData{IntrinsicType::kAsin, ParamType::kF32, "asin"},
IntrinsicData{IntrinsicType::kAtan, ParamType::kF32, "atan"},
IntrinsicData{IntrinsicType::kAtan2, ParamType::kF32, "atan"},
IntrinsicData{IntrinsicType::kCeil, ParamType::kF32, "ceil"},
IntrinsicData{IntrinsicType::kClamp, ParamType::kF32, "clamp"},
IntrinsicData{IntrinsicType::kClamp, ParamType::kU32, "clamp"},
IntrinsicData{IntrinsicType::kCos, ParamType::kF32, "cos"},
IntrinsicData{IntrinsicType::kCosh, ParamType::kF32, "cosh"},
IntrinsicData{IntrinsicType::kCountOneBits, ParamType::kU32,
"countbits"},
IntrinsicData{IntrinsicType::kCross, ParamType::kF32, "cross"},
IntrinsicData{IntrinsicType::kDeterminant, ParamType::kF32,
"determinant"},
IntrinsicData{IntrinsicType::kDistance, ParamType::kF32, "distance"},
IntrinsicData{IntrinsicType::kDot, ParamType::kF32, "dot"},
IntrinsicData{IntrinsicType::kDpdx, ParamType::kF32, "ddx"},
IntrinsicData{IntrinsicType::kDpdxCoarse, ParamType::kF32,
"ddx_coarse"},
IntrinsicData{IntrinsicType::kDpdxFine, ParamType::kF32, "ddx_fine"},
IntrinsicData{IntrinsicType::kDpdy, ParamType::kF32, "ddy"},
IntrinsicData{IntrinsicType::kDpdyCoarse, ParamType::kF32,
"ddy_coarse"},
IntrinsicData{IntrinsicType::kDpdyFine, ParamType::kF32, "ddy_fine"},
IntrinsicData{IntrinsicType::kExp, ParamType::kF32, "exp"},
IntrinsicData{IntrinsicType::kExp2, ParamType::kF32, "exp2"},
IntrinsicData{IntrinsicType::kFaceForward, ParamType::kF32,
"faceforward"},
IntrinsicData{IntrinsicType::kFloor, ParamType::kF32, "floor"},
IntrinsicData{IntrinsicType::kFma, ParamType::kF32, "mad"},
IntrinsicData{IntrinsicType::kFract, ParamType::kF32, "frac"},
IntrinsicData{IntrinsicType::kFwidth, ParamType::kF32, "fwidth"},
IntrinsicData{IntrinsicType::kFwidthCoarse, ParamType::kF32, "fwidth"},
IntrinsicData{IntrinsicType::kFwidthFine, ParamType::kF32, "fwidth"},
IntrinsicData{IntrinsicType::kInverseSqrt, ParamType::kF32, "rsqrt"},
IntrinsicData{IntrinsicType::kIsFinite, ParamType::kF32, "isfinite"},
IntrinsicData{IntrinsicType::kIsInf, ParamType::kF32, "isinf"},
IntrinsicData{IntrinsicType::kIsNan, ParamType::kF32, "isnan"},
IntrinsicData{IntrinsicType::kLdexp, ParamType::kF32, "ldexp"},
IntrinsicData{IntrinsicType::kLength, ParamType::kF32, "length"},
IntrinsicData{IntrinsicType::kLog, ParamType::kF32, "log"},
IntrinsicData{IntrinsicType::kLog2, ParamType::kF32, "log2"},
IntrinsicData{IntrinsicType::kMax, ParamType::kF32, "max"},
IntrinsicData{IntrinsicType::kMax, ParamType::kU32, "max"},
IntrinsicData{IntrinsicType::kMin, ParamType::kF32, "min"},
IntrinsicData{IntrinsicType::kMin, ParamType::kU32, "min"},
IntrinsicData{IntrinsicType::kMix, ParamType::kF32, "mix"},
IntrinsicData{IntrinsicType::kNormalize, ParamType::kF32, "normalize"},
IntrinsicData{IntrinsicType::kPow, ParamType::kF32, "pow"},
IntrinsicData{IntrinsicType::kReflect, ParamType::kF32, "reflect"},
IntrinsicData{IntrinsicType::kReverseBits, ParamType::kU32,
"reversebits"},
IntrinsicData{IntrinsicType::kRound, ParamType::kU32, "round"},
IntrinsicData{IntrinsicType::kSign, ParamType::kF32, "sign"},
IntrinsicData{IntrinsicType::kSin, ParamType::kF32, "sin"},
IntrinsicData{IntrinsicType::kSinh, ParamType::kF32, "sinh"},
IntrinsicData{IntrinsicType::kSmoothStep, ParamType::kF32,
"smoothstep"},
IntrinsicData{IntrinsicType::kSqrt, ParamType::kF32, "sqrt"},
IntrinsicData{IntrinsicType::kStep, ParamType::kF32, "step"},
IntrinsicData{IntrinsicType::kTan, ParamType::kF32, "tan"},
IntrinsicData{IntrinsicType::kTanh, ParamType::kF32, "tanh"},
IntrinsicData{IntrinsicType::kTranspose, ParamType::kF32, "transpose"},
IntrinsicData{IntrinsicType::kTrunc, ParamType::kF32, "trunc"}));
BuiltinData{BuiltinType::kAbs, ParamType::kF32, "abs"},
BuiltinData{BuiltinType::kAbs, ParamType::kU32, "abs"},
BuiltinData{BuiltinType::kAcos, ParamType::kF32, "acos"},
BuiltinData{BuiltinType::kAll, ParamType::kBool, "all"},
BuiltinData{BuiltinType::kAny, ParamType::kBool, "any"},
BuiltinData{BuiltinType::kAsin, ParamType::kF32, "asin"},
BuiltinData{BuiltinType::kAtan, ParamType::kF32, "atan"},
BuiltinData{BuiltinType::kAtan2, ParamType::kF32, "atan"},
BuiltinData{BuiltinType::kCeil, ParamType::kF32, "ceil"},
BuiltinData{BuiltinType::kClamp, ParamType::kF32, "clamp"},
BuiltinData{BuiltinType::kClamp, ParamType::kU32, "clamp"},
BuiltinData{BuiltinType::kCos, ParamType::kF32, "cos"},
BuiltinData{BuiltinType::kCosh, ParamType::kF32, "cosh"},
BuiltinData{BuiltinType::kCountOneBits, ParamType::kU32, "countbits"},
BuiltinData{BuiltinType::kCross, ParamType::kF32, "cross"},
BuiltinData{BuiltinType::kDeterminant, ParamType::kF32, "determinant"},
BuiltinData{BuiltinType::kDistance, ParamType::kF32, "distance"},
BuiltinData{BuiltinType::kDot, ParamType::kF32, "dot"},
BuiltinData{BuiltinType::kDpdx, ParamType::kF32, "ddx"},
BuiltinData{BuiltinType::kDpdxCoarse, ParamType::kF32, "ddx_coarse"},
BuiltinData{BuiltinType::kDpdxFine, ParamType::kF32, "ddx_fine"},
BuiltinData{BuiltinType::kDpdy, ParamType::kF32, "ddy"},
BuiltinData{BuiltinType::kDpdyCoarse, ParamType::kF32, "ddy_coarse"},
BuiltinData{BuiltinType::kDpdyFine, ParamType::kF32, "ddy_fine"},
BuiltinData{BuiltinType::kExp, ParamType::kF32, "exp"},
BuiltinData{BuiltinType::kExp2, ParamType::kF32, "exp2"},
BuiltinData{BuiltinType::kFaceForward, ParamType::kF32, "faceforward"},
BuiltinData{BuiltinType::kFloor, ParamType::kF32, "floor"},
BuiltinData{BuiltinType::kFma, ParamType::kF32, "mad"},
BuiltinData{BuiltinType::kFract, ParamType::kF32, "frac"},
BuiltinData{BuiltinType::kFwidth, ParamType::kF32, "fwidth"},
BuiltinData{BuiltinType::kFwidthCoarse, ParamType::kF32, "fwidth"},
BuiltinData{BuiltinType::kFwidthFine, ParamType::kF32, "fwidth"},
BuiltinData{BuiltinType::kInverseSqrt, ParamType::kF32, "rsqrt"},
BuiltinData{BuiltinType::kIsFinite, ParamType::kF32, "isfinite"},
BuiltinData{BuiltinType::kIsInf, ParamType::kF32, "isinf"},
BuiltinData{BuiltinType::kIsNan, ParamType::kF32, "isnan"},
BuiltinData{BuiltinType::kLdexp, ParamType::kF32, "ldexp"},
BuiltinData{BuiltinType::kLength, ParamType::kF32, "length"},
BuiltinData{BuiltinType::kLog, ParamType::kF32, "log"},
BuiltinData{BuiltinType::kLog2, ParamType::kF32, "log2"},
BuiltinData{BuiltinType::kMax, ParamType::kF32, "max"},
BuiltinData{BuiltinType::kMax, ParamType::kU32, "max"},
BuiltinData{BuiltinType::kMin, ParamType::kF32, "min"},
BuiltinData{BuiltinType::kMin, ParamType::kU32, "min"},
BuiltinData{BuiltinType::kMix, ParamType::kF32, "mix"},
BuiltinData{BuiltinType::kNormalize, ParamType::kF32, "normalize"},
BuiltinData{BuiltinType::kPow, ParamType::kF32, "pow"},
BuiltinData{BuiltinType::kReflect, ParamType::kF32, "reflect"},
BuiltinData{BuiltinType::kReverseBits, ParamType::kU32, "reversebits"},
BuiltinData{BuiltinType::kRound, ParamType::kU32, "round"},
BuiltinData{BuiltinType::kSign, ParamType::kF32, "sign"},
BuiltinData{BuiltinType::kSin, ParamType::kF32, "sin"},
BuiltinData{BuiltinType::kSinh, ParamType::kF32, "sinh"},
BuiltinData{BuiltinType::kSmoothStep, ParamType::kF32, "smoothstep"},
BuiltinData{BuiltinType::kSqrt, ParamType::kF32, "sqrt"},
BuiltinData{BuiltinType::kStep, ParamType::kF32, "step"},
BuiltinData{BuiltinType::kTan, ParamType::kF32, "tan"},
BuiltinData{BuiltinType::kTanh, ParamType::kF32, "tanh"},
BuiltinData{BuiltinType::kTranspose, ParamType::kF32, "transpose"},
BuiltinData{BuiltinType::kTrunc, ParamType::kF32, "trunc"}));
TEST_F(GlslGeneratorImplTest_Intrinsic, DISABLED_Intrinsic_IsNormal) {
TEST_F(GlslGeneratorImplTest_Builtin, DISABLED_Builtin_IsNormal) {
FAIL();
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Intrinsic_Call) {
TEST_F(GlslGeneratorImplTest_Builtin, Builtin_Call) {
auto* call = Call("dot", "param1", "param2");
Global("param1", ty.vec3<f32>(), ast::StorageClass::kPrivate);
@ -274,7 +267,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Intrinsic_Call) {
EXPECT_EQ(out.str(), "dot(param1, param2)");
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Select_Scalar) {
TEST_F(GlslGeneratorImplTest_Builtin, Select_Scalar) {
auto* call = Call("select", 1.0f, 2.0f, true);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@ -285,7 +278,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Select_Scalar) {
EXPECT_EQ(out.str(), "(true ? 2.0f : 1.0f)");
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Select_Vector) {
TEST_F(GlslGeneratorImplTest_Builtin, Select_Vector) {
auto* call =
Call("select", vec2<i32>(1, 2), vec2<i32>(3, 4), vec2<bool>(true, false));
WrapInFunction(CallStmt(call));
@ -298,7 +291,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Select_Vector) {
}
#if 0
TEST_F(GlslGeneratorImplTest_Intrinsic, Modf_Scalar) {
TEST_F(GlslGeneratorImplTest_Builtin, Modf_Scalar) {
auto* res = Var("res", ty.f32());
auto* call = Call("modf", 1.0f, AddressOf(res));
WrapInFunction(res, call);
@ -309,7 +302,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Modf_Scalar) {
EXPECT_THAT(gen.result(), HasSubstr("modf(1.0f, res)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Modf_Vector) {
TEST_F(GlslGeneratorImplTest_Builtin, Modf_Vector) {
auto* res = Var("res", ty.vec3<f32>());
auto* call = Call("modf", vec3<f32>(), AddressOf(res));
WrapInFunction(res, call);
@ -320,7 +313,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Modf_Vector) {
EXPECT_THAT(gen.result(), HasSubstr("modf(vec3(0.0f, 0.0f, 0.0f), res)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Frexp_Scalar_i32) {
TEST_F(GlslGeneratorImplTest_Builtin, Frexp_Scalar_i32) {
auto* exp = Var("exp", ty.i32());
auto* call = Call("frexp", 1.0f, AddressOf(exp));
WrapInFunction(exp, call);
@ -336,7 +329,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Frexp_Scalar_i32) {
)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Frexp_Vector_i32) {
TEST_F(GlslGeneratorImplTest_Builtin, Frexp_Vector_i32) {
auto* res = Var("res", ty.vec3<i32>());
auto* call = Call("frexp", vec3<f32>(), AddressOf(res));
WrapInFunction(res, call);
@ -352,7 +345,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Frexp_Vector_i32) {
)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, IsNormal_Scalar) {
TEST_F(GlslGeneratorImplTest_Builtin, IsNormal_Scalar) {
auto* val = Var("val", ty.f32());
auto* call = Call("isNormal", val);
WrapInFunction(val, call);
@ -367,7 +360,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, IsNormal_Scalar) {
)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, IsNormal_Vector) {
TEST_F(GlslGeneratorImplTest_Builtin, IsNormal_Vector) {
auto* val = Var("val", ty.vec3<f32>());
auto* call = Call("isNormal", val);
WrapInFunction(val, call);
@ -383,7 +376,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, IsNormal_Vector) {
}
#endif
TEST_F(GlslGeneratorImplTest_Intrinsic, Degrees_Scalar) {
TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Scalar) {
auto* val = Var("val", ty.f32());
auto* call = Call("degrees", val);
WrapInFunction(val, call);
@ -412,7 +405,7 @@ void main() {
)");
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Degrees_Vector) {
TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Vector) {
auto* val = Var("val", ty.vec3<f32>());
auto* call = Call("degrees", val);
WrapInFunction(val, call);
@ -441,7 +434,7 @@ void main() {
)");
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Radians_Scalar) {
TEST_F(GlslGeneratorImplTest_Builtin, Radians_Scalar) {
auto* val = Var("val", ty.f32());
auto* call = Call("radians", val);
WrapInFunction(val, call);
@ -470,7 +463,7 @@ void main() {
)");
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Radians_Vector) {
TEST_F(GlslGeneratorImplTest_Builtin, Radians_Vector) {
auto* val = Var("val", ty.vec3<f32>());
auto* call = Call("radians", val);
WrapInFunction(val, call);
@ -500,7 +493,7 @@ void main() {
}
#if 0
TEST_F(GlslGeneratorImplTest_Intrinsic, Pack4x8Snorm) {
TEST_F(GlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
auto* call = Call("pack4x8snorm", "p1");
Global("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -515,7 +508,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Pack4x8Snorm) {
"tint_tmp.z << 16 | tint_tmp.w << 24)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Pack4x8Unorm) {
TEST_F(GlslGeneratorImplTest_Builtin, Pack4x8Unorm) {
auto* call = Call("pack4x8unorm", "p1");
Global("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -530,7 +523,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Pack4x8Unorm) {
"tint_tmp.z << 16 | tint_tmp.w << 24)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Pack2x16Snorm) {
TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Snorm) {
auto* call = Call("pack2x16snorm", "p1");
Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -544,7 +537,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Pack2x16Snorm) {
EXPECT_THAT(out.str(), HasSubstr("asuint(tint_tmp.x | tint_tmp.y << 16)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Pack2x16Unorm) {
TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Unorm) {
auto* call = Call("pack2x16unorm", "p1");
Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -558,7 +551,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Pack2x16Unorm) {
EXPECT_THAT(out.str(), HasSubstr("(tint_tmp.x | tint_tmp.y << 16)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Pack2x16Float) {
TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Float) {
auto* call = Call("pack2x16float", "p1");
Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -571,7 +564,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Pack2x16Float) {
EXPECT_THAT(out.str(), HasSubstr("(tint_tmp.x | tint_tmp.y << 16)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Unpack4x8Snorm) {
TEST_F(GlslGeneratorImplTest_Builtin, Unpack4x8Snorm) {
auto* call = Call("unpack4x8snorm", "p1");
Global("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -588,7 +581,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Unpack4x8Snorm) {
HasSubstr("clamp(float4(tint_tmp) / 127.0, -1.0, 1.0)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Unpack4x8Unorm) {
TEST_F(GlslGeneratorImplTest_Builtin, Unpack4x8Unorm) {
auto* call = Call("unpack4x8unorm", "p1");
Global("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -605,7 +598,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Unpack4x8Unorm) {
EXPECT_THAT(out.str(), HasSubstr("float4(tint_tmp) / 255.0"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Unpack2x16Snorm) {
TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Snorm) {
auto* call = Call("unpack2x16snorm", "p1");
Global("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -622,7 +615,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Unpack2x16Snorm) {
HasSubstr("clamp(float2(tint_tmp) / 32767.0, -1.0, 1.0)"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Unpack2x16Unorm) {
TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Unorm) {
auto* call = Call("unpack2x16unorm", "p1");
Global("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -638,7 +631,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Unpack2x16Unorm) {
EXPECT_THAT(out.str(), HasSubstr("float2(tint_tmp) / 65535.0"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, Unpack2x16Float) {
TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Float) {
auto* call = Call("unpack2x16float", "p1");
Global("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -652,7 +645,7 @@ TEST_F(GlslGeneratorImplTest_Intrinsic, Unpack2x16Float) {
HasSubstr("f16tof32(uint2(tint_tmp & 0xffff, tint_tmp >> 16))"));
}
TEST_F(GlslGeneratorImplTest_Intrinsic, StorageBarrier) {
TEST_F(GlslGeneratorImplTest_Builtin, StorageBarrier) {
Func("main", {}, ty.void_(),
{CallStmt(Call("storageBarrier"))},
{
@ -671,7 +664,7 @@ void main() {
)");
}
TEST_F(GlslGeneratorImplTest_Intrinsic, WorkgroupBarrier) {
TEST_F(GlslGeneratorImplTest_Builtin, WorkgroupBarrier) {
Func("main", {}, ty.void_(),
{CallStmt(Call("workgroupBarrier"))},
{
@ -692,7 +685,7 @@ void main() {
#endif
TEST_F(GlslGeneratorImplTest_Intrinsic, DotI32) {
TEST_F(GlslGeneratorImplTest_Builtin, DotI32) {
Global("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(Call("dot", "v", "v")));
@ -719,7 +712,7 @@ void main() {
)");
}
TEST_F(GlslGeneratorImplTest_Intrinsic, DotU32) {
TEST_F(GlslGeneratorImplTest_Builtin, DotU32) {
Global("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(Call("dot", "v", "v")));

View File

@ -13,8 +13,8 @@
// limitations under the License.
#include "gmock/gmock.h"
#include "src/ast/builtin_texture_helper_test.h"
#include "src/ast/call_statement.h"
#include "src/ast/intrinsic_texture_helper_test.h"
#include "src/ast/stage_attribute.h"
#include "src/writer/glsl/test_helper.h"
@ -33,8 +33,8 @@ struct ExpectedResult {
};
ExpectedResult expected_texture_overload(
ast::intrinsic::test::ValidTextureOverload overload) {
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
ast::builtin::test::ValidTextureOverload overload) {
using ValidTextureOverload = ast::builtin::test::ValidTextureOverload;
switch (overload) {
case ValidTextureOverload::kDimensions1d:
case ValidTextureOverload::kDimensions2d:
@ -267,10 +267,10 @@ ExpectedResult expected_texture_overload(
return "<unmatched texture overload>";
} // NOLINT - Ignore the length of this function
class GlslGeneratorIntrinsicTextureTest
: public TestParamHelper<ast::intrinsic::test::TextureOverloadCase> {};
class GlslGeneratorBuiltinTextureTest
: public TestParamHelper<ast::builtin::test::TextureOverloadCase> {};
TEST_P(GlslGeneratorIntrinsicTextureTest, Call) {
TEST_P(GlslGeneratorBuiltinTextureTest, Call) {
auto param = GetParam();
param.BuildTextureVariable(this);
@ -292,9 +292,9 @@ TEST_P(GlslGeneratorIntrinsicTextureTest, Call) {
}
INSTANTIATE_TEST_SUITE_P(
GlslGeneratorIntrinsicTextureTest,
GlslGeneratorIntrinsicTextureTest,
testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
GlslGeneratorBuiltinTextureTest,
GlslGeneratorBuiltinTextureTest,
testing::ValuesIn(ast::builtin::test::TextureOverloadCase::ValidCases()));
} // namespace
} // namespace glsl

View File

@ -933,8 +933,8 @@ bool GeneratorImpl::EmitCall(std::ostream& out,
if (auto* func = target->As<sem::Function>()) {
return EmitFunctionCall(out, call, func);
}
if (auto* intrinsic = target->As<sem::Intrinsic>()) {
return EmitIntrinsicCall(out, call, intrinsic);
if (auto* builtin = target->As<sem::Builtin>()) {
return EmitBuiltinCall(out, call, builtin);
}
if (auto* conv = target->As<sem::TypeConversion>()) {
return EmitTypeConversion(out, call, conv);
@ -1001,44 +1001,44 @@ bool GeneratorImpl::EmitFunctionCall(std::ostream& out,
return true;
}
bool GeneratorImpl::EmitIntrinsicCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic) {
bool GeneratorImpl::EmitBuiltinCall(std::ostream& out,
const sem::Call* call,
const sem::Builtin* builtin) {
auto* expr = call->Declaration();
if (intrinsic->IsTexture()) {
return EmitTextureCall(out, call, intrinsic);
if (builtin->IsTexture()) {
return EmitTextureCall(out, call, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kSelect) {
if (builtin->Type() == sem::BuiltinType::kSelect) {
return EmitSelectCall(out, expr);
}
if (intrinsic->Type() == sem::IntrinsicType::kModf) {
return EmitModfCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kModf) {
return EmitModfCall(out, expr, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kFrexp) {
return EmitFrexpCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kFrexp) {
return EmitFrexpCall(out, expr, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kIsNormal) {
return EmitIsNormalCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kIsNormal) {
return EmitIsNormalCall(out, expr, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kDegrees) {
return EmitDegreesCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kDegrees) {
return EmitDegreesCall(out, expr, builtin);
}
if (intrinsic->Type() == sem::IntrinsicType::kRadians) {
return EmitRadiansCall(out, expr, intrinsic);
if (builtin->Type() == sem::BuiltinType::kRadians) {
return EmitRadiansCall(out, expr, builtin);
}
if (intrinsic->IsDataPacking()) {
return EmitDataPackingCall(out, expr, intrinsic);
if (builtin->IsDataPacking()) {
return EmitDataPackingCall(out, expr, builtin);
}
if (intrinsic->IsDataUnpacking()) {
return EmitDataUnpackingCall(out, expr, intrinsic);
if (builtin->IsDataUnpacking()) {
return EmitDataUnpackingCall(out, expr, builtin);
}
if (intrinsic->IsBarrier()) {
return EmitBarrierCall(out, intrinsic);
if (builtin->IsBarrier()) {
return EmitBarrierCall(out, builtin);
}
if (intrinsic->IsAtomic()) {
return EmitWorkgroupAtomicCall(out, expr, intrinsic);
if (builtin->IsAtomic()) {
return EmitWorkgroupAtomicCall(out, expr, builtin);
}
auto name = generate_builtin_name(intrinsic);
auto name = generate_builtin_name(builtin);
if (name.empty()) {
return false;
}
@ -1637,17 +1637,17 @@ bool GeneratorImpl::EmitStorageAtomicCall(
bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
const sem::Builtin* builtin) {
std::string result = UniqueIdentifier("atomic_result");
if (!intrinsic->ReturnType()->Is<sem::Void>()) {
if (!builtin->ReturnType()->Is<sem::Void>()) {
auto pre = line();
if (!EmitTypeAndName(pre, intrinsic->ReturnType(), ast::StorageClass::kNone,
if (!EmitTypeAndName(pre, builtin->ReturnType(), ast::StorageClass::kNone,
ast::Access::kUndefined, result)) {
return false;
}
pre << " = ";
if (!EmitZeroValue(pre, intrinsic->ReturnType())) {
if (!EmitZeroValue(pre, builtin->ReturnType())) {
return false;
}
pre << ";";
@ -1664,7 +1664,7 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
if (i > 0) {
pre << ", ";
}
if (i == 1 && intrinsic->Type() == sem::IntrinsicType::kAtomicSub) {
if (i == 1 && builtin->Type() == sem::BuiltinType::kAtomicSub) {
// Sub uses InterlockedAdd with the operand negated.
pre << "-";
}
@ -1682,8 +1682,8 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
return true;
};
switch (intrinsic->Type()) {
case sem::IntrinsicType::kAtomicLoad: {
switch (builtin->Type()) {
case sem::BuiltinType::kAtomicLoad: {
// HLSL does not have an InterlockedLoad, so we emulate it with
// InterlockedOr using 0 as the OR value
auto pre = line();
@ -1700,12 +1700,12 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
out << result;
return true;
}
case sem::IntrinsicType::kAtomicStore: {
case sem::BuiltinType::kAtomicStore: {
// HLSL does not have an InterlockedStore, so we emulate it with
// InterlockedExchange and discard the returned value
{ // T result = 0;
auto pre = line();
auto* value_ty = intrinsic->Parameters()[1]->Type()->UnwrapRef();
auto* value_ty = builtin->Parameters()[1]->Type()->UnwrapRef();
if (!EmitTypeAndName(pre, value_ty, ast::StorageClass::kNone,
ast::Access::kUndefined, result)) {
return false;
@ -1731,7 +1731,7 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
}
return true;
}
case sem::IntrinsicType::kAtomicCompareExchangeWeak: {
case sem::BuiltinType::kAtomicCompareExchangeWeak: {
auto* dest = expr->args[0];
auto* compare_value = expr->args[1];
auto* value = expr->args[2];
@ -1777,26 +1777,26 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
return true;
}
case sem::IntrinsicType::kAtomicAdd:
case sem::IntrinsicType::kAtomicSub:
case sem::BuiltinType::kAtomicAdd:
case sem::BuiltinType::kAtomicSub:
return call("InterlockedAdd");
case sem::IntrinsicType::kAtomicMax:
case sem::BuiltinType::kAtomicMax:
return call("InterlockedMax");
case sem::IntrinsicType::kAtomicMin:
case sem::BuiltinType::kAtomicMin:
return call("InterlockedMin");
case sem::IntrinsicType::kAtomicAnd:
case sem::BuiltinType::kAtomicAnd:
return call("InterlockedAnd");
case sem::IntrinsicType::kAtomicOr:
case sem::BuiltinType::kAtomicOr:
return call("InterlockedOr");
case sem::IntrinsicType::kAtomicXor:
case sem::BuiltinType::kAtomicXor:
return call("InterlockedXor");
case sem::IntrinsicType::kAtomicExchange:
case sem::BuiltinType::kAtomicExchange:
return call("InterlockedExchange");
default:
@ -1804,7 +1804,7 @@ bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
}
TINT_UNREACHABLE(Writer, diagnostics_)
<< "unsupported atomic intrinsic: " << intrinsic->Type();
<< "unsupported atomic builtin: " << builtin->Type();
return false;
}
@ -1835,11 +1835,11 @@ bool GeneratorImpl::EmitSelectCall(std::ostream& out,
bool GeneratorImpl::EmitModfCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
auto* ty = intrinsic->Parameters()[0]->Type();
auto* ty = builtin->Parameters()[0]->Type();
auto in = params[0];
std::string width;
@ -1850,7 +1850,7 @@ bool GeneratorImpl::EmitModfCall(std::ostream& out,
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
if (!EmitStructType(&helpers_,
intrinsic->ReturnType()->As<sem::Struct>())) {
builtin->ReturnType()->As<sem::Struct>())) {
return false;
}
@ -1858,7 +1858,7 @@ bool GeneratorImpl::EmitModfCall(std::ostream& out,
line(b) << "float" << width << " fract = modf(" << in << ", whole);";
{
auto l = line(b);
if (!EmitType(l, intrinsic->ReturnType(), ast::StorageClass::kNone,
if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
ast::Access::kUndefined, "")) {
return false;
}
@ -1871,11 +1871,11 @@ bool GeneratorImpl::EmitModfCall(std::ostream& out,
bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
auto* ty = intrinsic->Parameters()[0]->Type();
auto* ty = builtin->Parameters()[0]->Type();
auto in = params[0];
std::string width;
@ -1886,7 +1886,7 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
if (!EmitStructType(&helpers_,
intrinsic->ReturnType()->As<sem::Struct>())) {
builtin->ReturnType()->As<sem::Struct>())) {
return false;
}
@ -1894,7 +1894,7 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
line(b) << "float" << width << " sig = frexp(" << in << ", exp);";
{
auto l = line(b);
if (!EmitType(l, intrinsic->ReturnType(), ast::StorageClass::kNone,
if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
ast::Access::kUndefined, "")) {
return false;
}
@ -1907,12 +1907,12 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
bool GeneratorImpl::EmitIsNormalCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
// HLSL doesn't have a isNormal intrinsic, we need to emulate
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
// HLSL doesn't have a isNormal builtin, we need to emulate
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
auto* input_ty = intrinsic->Parameters()[0]->Type();
auto* input_ty = builtin->Parameters()[0]->Type();
std::string width;
if (auto* vec = input_ty->As<sem::Vector>()) {
@ -1935,9 +1935,9 @@ bool GeneratorImpl::EmitIsNormalCall(std::ostream& out,
bool GeneratorImpl::EmitDegreesCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
line(b) << "return " << params[0] << " * " << std::setprecision(20)
<< sem::kRadToDeg << ";";
@ -1947,9 +1947,9 @@ bool GeneratorImpl::EmitDegreesCall(std::ostream& out,
bool GeneratorImpl::EmitRadiansCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
line(b) << "return " << params[0] << " * " << std::setprecision(20)
<< sem::kDegToRad << ";";
@ -1959,28 +1959,28 @@ bool GeneratorImpl::EmitRadiansCall(std::ostream& out,
bool GeneratorImpl::EmitDataPackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
uint32_t dims = 2;
bool is_signed = false;
uint32_t scale = 65535;
if (intrinsic->Type() == sem::IntrinsicType::kPack4x8snorm ||
intrinsic->Type() == sem::IntrinsicType::kPack4x8unorm) {
if (builtin->Type() == sem::BuiltinType::kPack4x8snorm ||
builtin->Type() == sem::BuiltinType::kPack4x8unorm) {
dims = 4;
scale = 255;
}
if (intrinsic->Type() == sem::IntrinsicType::kPack4x8snorm ||
intrinsic->Type() == sem::IntrinsicType::kPack2x16snorm) {
if (builtin->Type() == sem::BuiltinType::kPack4x8snorm ||
builtin->Type() == sem::BuiltinType::kPack2x16snorm) {
is_signed = true;
scale = (scale - 1) / 2;
}
switch (intrinsic->Type()) {
case sem::IntrinsicType::kPack4x8snorm:
case sem::IntrinsicType::kPack4x8unorm:
case sem::IntrinsicType::kPack2x16snorm:
case sem::IntrinsicType::kPack2x16unorm: {
switch (builtin->Type()) {
case sem::BuiltinType::kPack4x8snorm:
case sem::BuiltinType::kPack4x8unorm:
case sem::BuiltinType::kPack2x16snorm:
case sem::BuiltinType::kPack2x16unorm: {
{
auto l = line(b);
l << (is_signed ? "" : "u") << "int" << dims
@ -2007,7 +2007,7 @@ bool GeneratorImpl::EmitDataPackingCall(std::ostream& out,
}
break;
}
case sem::IntrinsicType::kPack2x16float: {
case sem::BuiltinType::kPack2x16float: {
line(b) << "uint2 i = f32tof16(" << params[0] << ");";
line(b) << "return i.x | (i.y << 16);";
break;
@ -2015,7 +2015,7 @@ bool GeneratorImpl::EmitDataPackingCall(std::ostream& out,
default:
diagnostics_.add_error(
diag::System::Writer,
"Internal error: unhandled data packing intrinsic");
"Internal error: unhandled data packing builtin");
return false;
}
@ -2025,26 +2025,26 @@ bool GeneratorImpl::EmitDataPackingCall(std::ostream& out,
bool GeneratorImpl::EmitDataUnpackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
uint32_t dims = 2;
bool is_signed = false;
uint32_t scale = 65535;
if (intrinsic->Type() == sem::IntrinsicType::kUnpack4x8snorm ||
intrinsic->Type() == sem::IntrinsicType::kUnpack4x8unorm) {
if (builtin->Type() == sem::BuiltinType::kUnpack4x8snorm ||
builtin->Type() == sem::BuiltinType::kUnpack4x8unorm) {
dims = 4;
scale = 255;
}
if (intrinsic->Type() == sem::IntrinsicType::kUnpack4x8snorm ||
intrinsic->Type() == sem::IntrinsicType::kUnpack2x16snorm) {
if (builtin->Type() == sem::BuiltinType::kUnpack4x8snorm ||
builtin->Type() == sem::BuiltinType::kUnpack2x16snorm) {
is_signed = true;
scale = (scale - 1) / 2;
}
switch (intrinsic->Type()) {
case sem::IntrinsicType::kUnpack4x8snorm:
case sem::IntrinsicType::kUnpack2x16snorm: {
switch (builtin->Type()) {
case sem::BuiltinType::kUnpack4x8snorm:
case sem::BuiltinType::kUnpack2x16snorm: {
line(b) << "int j = int(" << params[0] << ");";
{ // Perform sign extension on the converted values.
auto l = line(b);
@ -2060,8 +2060,8 @@ bool GeneratorImpl::EmitDataUnpackingCall(std::ostream& out,
<< ".0, " << (is_signed ? "-1.0" : "0.0") << ", 1.0);";
break;
}
case sem::IntrinsicType::kUnpack4x8unorm:
case sem::IntrinsicType::kUnpack2x16unorm: {
case sem::BuiltinType::kUnpack4x8unorm:
case sem::BuiltinType::kUnpack2x16unorm: {
line(b) << "uint j = " << params[0] << ";";
{
auto l = line(b);
@ -2078,14 +2078,14 @@ bool GeneratorImpl::EmitDataUnpackingCall(std::ostream& out,
line(b) << "return float" << dims << "(i) / " << scale << ".0;";
break;
}
case sem::IntrinsicType::kUnpack2x16float:
case sem::BuiltinType::kUnpack2x16float:
line(b) << "uint i = " << params[0] << ";";
line(b) << "return f16tof32(uint2(i & 0xffff, i >> 16));";
break;
default:
diagnostics_.add_error(
diag::System::Writer,
"Internal error: unhandled data packing intrinsic");
"Internal error: unhandled data packing builtin");
return false;
}
@ -2094,16 +2094,16 @@ bool GeneratorImpl::EmitDataUnpackingCall(std::ostream& out,
}
bool GeneratorImpl::EmitBarrierCall(std::ostream& out,
const sem::Intrinsic* intrinsic) {
const sem::Builtin* builtin) {
// TODO(crbug.com/tint/661): Combine sequential barriers to a single
// instruction.
if (intrinsic->Type() == sem::IntrinsicType::kWorkgroupBarrier) {
if (builtin->Type() == sem::BuiltinType::kWorkgroupBarrier) {
out << "GroupMemoryBarrierWithGroupSync()";
} else if (intrinsic->Type() == sem::IntrinsicType::kStorageBarrier) {
} else if (builtin->Type() == sem::BuiltinType::kStorageBarrier) {
out << "DeviceMemoryBarrierWithGroupSync()";
} else {
TINT_UNREACHABLE(Writer, diagnostics_)
<< "unexpected barrier intrinsic type " << sem::str(intrinsic->Type());
<< "unexpected barrier builtin type " << sem::str(builtin->Type());
return false;
}
return true;
@ -2111,10 +2111,10 @@ bool GeneratorImpl::EmitBarrierCall(std::ostream& out,
bool GeneratorImpl::EmitTextureCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic) {
const sem::Builtin* builtin) {
using Usage = sem::ParameterUsage;
auto& signature = intrinsic->Signature();
auto& signature = builtin->Signature();
auto* expr = call->Declaration();
auto arguments = expr->args;
@ -2132,19 +2132,19 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
auto* texture_type = TypeOf(texture)->UnwrapRef()->As<sem::Texture>();
switch (intrinsic->Type()) {
case sem::IntrinsicType::kTextureDimensions:
case sem::IntrinsicType::kTextureNumLayers:
case sem::IntrinsicType::kTextureNumLevels:
case sem::IntrinsicType::kTextureNumSamples: {
// All of these intrinsics use the GetDimensions() method on the texture
switch (builtin->Type()) {
case sem::BuiltinType::kTextureDimensions:
case sem::BuiltinType::kTextureNumLayers:
case sem::BuiltinType::kTextureNumLevels:
case sem::BuiltinType::kTextureNumSamples: {
// All of these builtins use the GetDimensions() method on the texture
bool is_ms = texture_type->IsAnyOf<sem::MultisampledTexture,
sem::DepthMultisampledTexture>();
int num_dimensions = 0;
std::string swizzle;
switch (intrinsic->Type()) {
case sem::IntrinsicType::kTextureDimensions:
switch (builtin->Type()) {
case sem::BuiltinType::kTextureDimensions:
switch (texture_type->dim()) {
case ast::TextureDimension::kNone:
TINT_ICE(Writer, diagnostics_) << "texture dimension is kNone";
@ -2172,7 +2172,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
break;
}
break;
case sem::IntrinsicType::kTextureNumLayers:
case sem::BuiltinType::kTextureNumLayers:
switch (texture_type->dim()) {
default:
TINT_ICE(Writer, diagnostics_)
@ -2188,7 +2188,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
break;
}
break;
case sem::IntrinsicType::kTextureNumLevels:
case sem::BuiltinType::kTextureNumLevels:
switch (texture_type->dim()) {
default:
TINT_ICE(Writer, diagnostics_)
@ -2211,7 +2211,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
break;
}
break;
case sem::IntrinsicType::kTextureNumSamples:
case sem::BuiltinType::kTextureNumSamples:
switch (texture_type->dim()) {
default:
TINT_ICE(Writer, diagnostics_)
@ -2228,7 +2228,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
}
break;
default:
TINT_ICE(Writer, diagnostics_) << "unexpected intrinsic";
TINT_ICE(Writer, diagnostics_) << "unexpected builtin";
return false;
}
@ -2251,7 +2251,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
if (num_dimensions > 4) {
TINT_ICE(Writer, diagnostics_)
<< "Texture query intrinsic temporary vector has " << num_dimensions
<< "Texture query builtin temporary vector has " << num_dimensions
<< " dimensions";
return false;
}
@ -2276,7 +2276,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
return false;
}
pre << ", ";
} else if (intrinsic->Type() == sem::IntrinsicType::kTextureNumLevels) {
} else if (builtin->Type() == sem::BuiltinType::kTextureNumLevels) {
pre << "0, ";
}
@ -2314,44 +2314,44 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
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 intrinsic overload does
// last value of the coordinates argument. If the WGSL builtin overload does
// not have a level parameter and pack_level_in_coords is true, then a zero
// mip level will be inserted.
bool pack_level_in_coords = false;
uint32_t hlsl_ret_width = 4u;
switch (intrinsic->Type()) {
case sem::IntrinsicType::kTextureSample:
switch (builtin->Type()) {
case sem::BuiltinType::kTextureSample:
out << ".Sample(";
break;
case sem::IntrinsicType::kTextureSampleBias:
case sem::BuiltinType::kTextureSampleBias:
out << ".SampleBias(";
break;
case sem::IntrinsicType::kTextureSampleLevel:
case sem::BuiltinType::kTextureSampleLevel:
out << ".SampleLevel(";
break;
case sem::IntrinsicType::kTextureSampleGrad:
case sem::BuiltinType::kTextureSampleGrad:
out << ".SampleGrad(";
break;
case sem::IntrinsicType::kTextureSampleCompare:
case sem::BuiltinType::kTextureSampleCompare:
out << ".SampleCmp(";
hlsl_ret_width = 1;
break;
case sem::IntrinsicType::kTextureSampleCompareLevel:
case sem::BuiltinType::kTextureSampleCompareLevel:
out << ".SampleCmpLevelZero(";
hlsl_ret_width = 1;
break;
case sem::IntrinsicType::kTextureLoad:
case sem::BuiltinType::kTextureLoad:
out << ".Load(";
// Multisampled textures do not support mip-levels.
if (!texture_type->Is<sem::MultisampledTexture>()) {
pack_level_in_coords = true;
}
break;
case sem::IntrinsicType::kTextureGather:
case sem::BuiltinType::kTextureGather:
out << ".Gather";
if (intrinsic->Parameters()[0]->Usage() ==
if (builtin->Parameters()[0]->Usage() ==
sem::ParameterUsage::kComponent) {
switch (call->Arguments()[0]->ConstantValue().Elements()[0].i32) {
case 0:
@ -2370,17 +2370,17 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
}
out << "(";
break;
case sem::IntrinsicType::kTextureGatherCompare:
case sem::BuiltinType::kTextureGatherCompare:
out << ".GatherCmp(";
break;
case sem::IntrinsicType::kTextureStore:
case sem::BuiltinType::kTextureStore:
out << "[";
break;
default:
diagnostics_.add_error(
diag::System::Writer,
"Internal compiler error: Unhandled texture intrinsic '" +
std::string(intrinsic->str()) + "'");
"Internal compiler error: Unhandled texture builtin '" +
std::string(builtin->str()) + "'");
return false;
}
@ -2451,7 +2451,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
}
}
if (intrinsic->Type() == sem::IntrinsicType::kTextureStore) {
if (builtin->Type() == sem::BuiltinType::kTextureStore) {
out << "] = ";
if (!EmitExpression(out, arg(Usage::kValue))) {
return false;
@ -2459,11 +2459,11 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
} else {
out << ")";
// If the intrinsic return type does not match the number of elements of the
// HLSL intrinsic, we need to swizzle the expression to generate the correct
// If the builtin return type does not match the number of elements of the
// HLSL builtin, we need to swizzle the expression to generate the correct
// number of components.
uint32_t wgsl_ret_width = 1;
if (auto* vec = intrinsic->ReturnType()->As<sem::Vector>()) {
if (auto* vec = builtin->ReturnType()->As<sem::Vector>()) {
wgsl_ret_width = vec->Width();
}
if (wgsl_ret_width < hlsl_ret_width) {
@ -2476,7 +2476,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
TINT_ICE(Writer, diagnostics_)
<< "WGSL return width (" << wgsl_ret_width
<< ") is wider than HLSL return width (" << hlsl_ret_width << ") for "
<< intrinsic->Type();
<< builtin->Type();
return false;
}
}
@ -2484,92 +2484,91 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
return true;
}
std::string GeneratorImpl::generate_builtin_name(
const sem::Intrinsic* intrinsic) {
switch (intrinsic->Type()) {
case sem::IntrinsicType::kAbs:
case sem::IntrinsicType::kAcos:
case sem::IntrinsicType::kAll:
case sem::IntrinsicType::kAny:
case sem::IntrinsicType::kAsin:
case sem::IntrinsicType::kAtan:
case sem::IntrinsicType::kAtan2:
case sem::IntrinsicType::kCeil:
case sem::IntrinsicType::kClamp:
case sem::IntrinsicType::kCos:
case sem::IntrinsicType::kCosh:
case sem::IntrinsicType::kCross:
case sem::IntrinsicType::kDeterminant:
case sem::IntrinsicType::kDistance:
case sem::IntrinsicType::kDot:
case sem::IntrinsicType::kExp:
case sem::IntrinsicType::kExp2:
case sem::IntrinsicType::kFloor:
case sem::IntrinsicType::kFrexp:
case sem::IntrinsicType::kLdexp:
case sem::IntrinsicType::kLength:
case sem::IntrinsicType::kLog:
case sem::IntrinsicType::kLog2:
case sem::IntrinsicType::kMax:
case sem::IntrinsicType::kMin:
case sem::IntrinsicType::kModf:
case sem::IntrinsicType::kNormalize:
case sem::IntrinsicType::kPow:
case sem::IntrinsicType::kReflect:
case sem::IntrinsicType::kRefract:
case sem::IntrinsicType::kRound:
case sem::IntrinsicType::kSign:
case sem::IntrinsicType::kSin:
case sem::IntrinsicType::kSinh:
case sem::IntrinsicType::kSqrt:
case sem::IntrinsicType::kStep:
case sem::IntrinsicType::kTan:
case sem::IntrinsicType::kTanh:
case sem::IntrinsicType::kTranspose:
case sem::IntrinsicType::kTrunc:
return intrinsic->str();
case sem::IntrinsicType::kCountOneBits:
std::string GeneratorImpl::generate_builtin_name(const sem::Builtin* builtin) {
switch (builtin->Type()) {
case sem::BuiltinType::kAbs:
case sem::BuiltinType::kAcos:
case sem::BuiltinType::kAll:
case sem::BuiltinType::kAny:
case sem::BuiltinType::kAsin:
case sem::BuiltinType::kAtan:
case sem::BuiltinType::kAtan2:
case sem::BuiltinType::kCeil:
case sem::BuiltinType::kClamp:
case sem::BuiltinType::kCos:
case sem::BuiltinType::kCosh:
case sem::BuiltinType::kCross:
case sem::BuiltinType::kDeterminant:
case sem::BuiltinType::kDistance:
case sem::BuiltinType::kDot:
case sem::BuiltinType::kExp:
case sem::BuiltinType::kExp2:
case sem::BuiltinType::kFloor:
case sem::BuiltinType::kFrexp:
case sem::BuiltinType::kLdexp:
case sem::BuiltinType::kLength:
case sem::BuiltinType::kLog:
case sem::BuiltinType::kLog2:
case sem::BuiltinType::kMax:
case sem::BuiltinType::kMin:
case sem::BuiltinType::kModf:
case sem::BuiltinType::kNormalize:
case sem::BuiltinType::kPow:
case sem::BuiltinType::kReflect:
case sem::BuiltinType::kRefract:
case sem::BuiltinType::kRound:
case sem::BuiltinType::kSign:
case sem::BuiltinType::kSin:
case sem::BuiltinType::kSinh:
case sem::BuiltinType::kSqrt:
case sem::BuiltinType::kStep:
case sem::BuiltinType::kTan:
case sem::BuiltinType::kTanh:
case sem::BuiltinType::kTranspose:
case sem::BuiltinType::kTrunc:
return builtin->str();
case sem::BuiltinType::kCountOneBits:
return "countbits";
case sem::IntrinsicType::kDpdx:
case sem::BuiltinType::kDpdx:
return "ddx";
case sem::IntrinsicType::kDpdxCoarse:
case sem::BuiltinType::kDpdxCoarse:
return "ddx_coarse";
case sem::IntrinsicType::kDpdxFine:
case sem::BuiltinType::kDpdxFine:
return "ddx_fine";
case sem::IntrinsicType::kDpdy:
case sem::BuiltinType::kDpdy:
return "ddy";
case sem::IntrinsicType::kDpdyCoarse:
case sem::BuiltinType::kDpdyCoarse:
return "ddy_coarse";
case sem::IntrinsicType::kDpdyFine:
case sem::BuiltinType::kDpdyFine:
return "ddy_fine";
case sem::IntrinsicType::kFaceForward:
case sem::BuiltinType::kFaceForward:
return "faceforward";
case sem::IntrinsicType::kFract:
case sem::BuiltinType::kFract:
return "frac";
case sem::IntrinsicType::kFma:
case sem::BuiltinType::kFma:
return "mad";
case sem::IntrinsicType::kFwidth:
case sem::IntrinsicType::kFwidthCoarse:
case sem::IntrinsicType::kFwidthFine:
case sem::BuiltinType::kFwidth:
case sem::BuiltinType::kFwidthCoarse:
case sem::BuiltinType::kFwidthFine:
return "fwidth";
case sem::IntrinsicType::kInverseSqrt:
case sem::BuiltinType::kInverseSqrt:
return "rsqrt";
case sem::IntrinsicType::kIsFinite:
case sem::BuiltinType::kIsFinite:
return "isfinite";
case sem::IntrinsicType::kIsInf:
case sem::BuiltinType::kIsInf:
return "isinf";
case sem::IntrinsicType::kIsNan:
case sem::BuiltinType::kIsNan:
return "isnan";
case sem::IntrinsicType::kMix:
case sem::BuiltinType::kMix:
return "lerp";
case sem::IntrinsicType::kReverseBits:
case sem::BuiltinType::kReverseBits:
return "reversebits";
case sem::IntrinsicType::kSmoothStep:
case sem::BuiltinType::kSmoothStep:
return "smoothstep";
default:
diagnostics_.add_error(
diag::System::Writer,
"Unknown builtin method: " + std::string(intrinsic->str()));
"Unknown builtin method: " + std::string(builtin->str()));
}
return "";
@ -3892,28 +3891,28 @@ bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
}
template <typename F>
bool GeneratorImpl::CallIntrinsicHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Intrinsic* intrinsic,
F&& build) {
bool GeneratorImpl::CallBuiltinHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Builtin* builtin,
F&& build) {
// Generate the helper function if it hasn't been created already
auto fn = utils::GetOrCreate(intrinsics_, intrinsic, [&]() -> std::string {
auto fn = utils::GetOrCreate(builtins_, builtin, [&]() -> std::string {
TextBuffer b;
TINT_DEFER(helpers_.Append(b));
auto fn_name =
UniqueIdentifier(std::string("tint_") + sem::str(intrinsic->Type()));
UniqueIdentifier(std::string("tint_") + sem::str(builtin->Type()));
std::vector<std::string> parameter_names;
{
auto decl = line(&b);
if (!EmitTypeAndName(decl, intrinsic->ReturnType(),
if (!EmitTypeAndName(decl, builtin->ReturnType(),
ast::StorageClass::kNone, ast::Access::kUndefined,
fn_name)) {
return "";
}
{
ScopedParen sp(decl);
for (auto* param : intrinsic->Parameters()) {
for (auto* param : builtin->Parameters()) {
if (!parameter_names.empty()) {
decl << ", ";
}

View File

@ -44,7 +44,7 @@ namespace tint {
// Forward declarations
namespace sem {
class Call;
class Intrinsic;
class Builtin;
class TypeConstructor;
class TypeConversion;
} // namespace sem
@ -145,14 +145,14 @@ class GeneratorImpl : public TextGenerator {
bool EmitFunctionCall(std::ostream& out,
const sem::Call* call,
const sem::Function* function);
/// Handles generating an intrinsic call expression
/// Handles generating a builtin call expression
/// @param out the output of the expression stream
/// @param call the call expression
/// @param intrinsic the intrinsic being called
/// @param builtin the builtin being called
/// @returns true if the expression is emitted
bool EmitIntrinsicCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic);
bool EmitBuiltinCall(std::ostream& out,
const sem::Call* call,
const sem::Builtin* builtin);
/// Handles generating a type conversion expression
/// @param out the output of the expression stream
/// @param call the call expression
@ -191,9 +191,9 @@ class GeneratorImpl : public TextGenerator {
const transform::DecomposeMemoryAccess::Intrinsic* intrinsic);
/// Handles generating a barrier intrinsic call
/// @param out the output of the expression stream
/// @param intrinsic the semantic information for the barrier intrinsic
/// @param builtin the semantic information for the barrier builtin
/// @returns true if the call expression is emitted
bool EmitBarrierCall(std::ostream& out, const sem::Intrinsic* intrinsic);
bool EmitBarrierCall(std::ostream& out, const sem::Builtin* builtin);
/// Handles generating an atomic intrinsic call for a storage buffer variable
/// @param out the output of the expression stream
/// @param expr the call expression
@ -206,81 +206,81 @@ class GeneratorImpl : public TextGenerator {
/// Handles generating an atomic intrinsic call for a workgroup variable
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the atomic intrinsic
/// @param builtin the semantic information for the atomic builtin
/// @returns true if the call expression is emitted
bool EmitWorkgroupAtomicCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
const sem::Builtin* builtin);
/// Handles generating a call to a texture function (`textureSample`,
/// `textureSampleGrad`, etc)
/// @param out the output of the expression stream
/// @param call the call expression
/// @param intrinsic the semantic information for the texture intrinsic
/// @param builtin the semantic information for the texture builtin
/// @returns true if the call expression is emitted
bool EmitTextureCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `select()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `select()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @returns true if the call expression is emitted
bool EmitSelectCall(std::ostream& out, const ast::CallExpression* expr);
/// Handles generating a call to the `modf()` intrinsic
/// Handles generating a call to the `modf()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitModfCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `frexp()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `frexp()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitFrexpCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `isNormal()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `isNormal()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitIsNormalCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `degrees()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `degrees()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitDegreesCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `radians()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `radians()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitRadiansCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to data packing intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to data packing builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the texture intrinsic
/// @param builtin the semantic information for the texture builtin
/// @returns true if the call expression is emitted
bool EmitDataPackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to data unpacking intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to data unpacking builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the texture intrinsic
/// @param builtin the semantic information for the texture builtin
/// @returns true if the call expression is emitted
bool EmitDataUnpackingCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
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
@ -473,9 +473,9 @@ class GeneratorImpl : public TextGenerator {
const sem::Matrix* mat);
/// Handles generating a builtin method name
/// @param intrinsic the semantic info for the intrinsic
/// @param builtin the semantic info for the builtin
/// @returns the name or "" if not valid
std::string generate_builtin_name(const sem::Intrinsic* intrinsic);
std::string generate_builtin_name(const sem::Builtin* builtin);
/// Converts a builtin to an attribute name
/// @param builtin the builtin to convert
/// @returns the string name of the builtin or blank on error
@ -513,13 +513,13 @@ class GeneratorImpl : public TextGenerator {
};
};
/// CallIntrinsicHelper will call the intrinsic helper function, creating it
/// if it hasn't been built already. If the intrinsic needs to be built then
/// CallIntrinsicHelper will generate the function signature and will call
/// CallBuiltinHelper will call the builtin helper function, creating it
/// if it hasn't been built already. If the builtin needs to be built then
/// CallBuiltinHelper will generate the function signature and will call
/// `build` to emit the body of the function.
/// @param out the output of the expression stream
/// @param call the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @param build a function with the signature:
/// `bool(TextBuffer* buffer, const std::vector<std::string>& params)`
/// Where:
@ -527,16 +527,16 @@ class GeneratorImpl : public TextGenerator {
/// `params` is the name of all the generated function parameters
/// @returns true if the call expression is emitted
template <typename F>
bool CallIntrinsicHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Intrinsic* intrinsic,
F&& build);
bool CallBuiltinHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Builtin* builtin,
F&& build);
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::Intrinsic*, std::string> intrinsics_;
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_;
std::unordered_map<const sem::Matrix*, std::string>

View File

@ -23,11 +23,11 @@ namespace writer {
namespace hlsl {
namespace {
using IntrinsicType = sem::IntrinsicType;
using BuiltinType = sem::BuiltinType;
using ::testing::HasSubstr;
using HlslGeneratorImplTest_Intrinsic = TestHelper;
using HlslGeneratorImplTest_Builtin = TestHelper;
enum class ParamType {
kF32,
@ -35,12 +35,12 @@ enum class ParamType {
kBool,
};
struct IntrinsicData {
IntrinsicType intrinsic;
struct BuiltinData {
BuiltinType builtin;
ParamType type;
const char* hlsl_name;
};
inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
out << data.hlsl_name;
switch (data.type) {
case ParamType::kF32:
@ -57,104 +57,104 @@ inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
return out;
}
const ast::CallExpression* GenerateCall(IntrinsicType intrinsic,
const ast::CallExpression* GenerateCall(BuiltinType builtin,
ParamType type,
ProgramBuilder* builder) {
std::string name;
std::ostringstream str(name);
str << intrinsic;
switch (intrinsic) {
case IntrinsicType::kAcos:
case IntrinsicType::kAsin:
case IntrinsicType::kAtan:
case IntrinsicType::kCeil:
case IntrinsicType::kCos:
case IntrinsicType::kCosh:
case IntrinsicType::kDpdx:
case IntrinsicType::kDpdxCoarse:
case IntrinsicType::kDpdxFine:
case IntrinsicType::kDpdy:
case IntrinsicType::kDpdyCoarse:
case IntrinsicType::kDpdyFine:
case IntrinsicType::kExp:
case IntrinsicType::kExp2:
case IntrinsicType::kFloor:
case IntrinsicType::kFract:
case IntrinsicType::kFwidth:
case IntrinsicType::kFwidthCoarse:
case IntrinsicType::kFwidthFine:
case IntrinsicType::kInverseSqrt:
case IntrinsicType::kIsFinite:
case IntrinsicType::kIsInf:
case IntrinsicType::kIsNan:
case IntrinsicType::kIsNormal:
case IntrinsicType::kLength:
case IntrinsicType::kLog:
case IntrinsicType::kLog2:
case IntrinsicType::kNormalize:
case IntrinsicType::kRound:
case IntrinsicType::kSin:
case IntrinsicType::kSinh:
case IntrinsicType::kSqrt:
case IntrinsicType::kTan:
case IntrinsicType::kTanh:
case IntrinsicType::kTrunc:
case IntrinsicType::kSign:
str << builtin;
switch (builtin) {
case BuiltinType::kAcos:
case BuiltinType::kAsin:
case BuiltinType::kAtan:
case BuiltinType::kCeil:
case BuiltinType::kCos:
case BuiltinType::kCosh:
case BuiltinType::kDpdx:
case BuiltinType::kDpdxCoarse:
case BuiltinType::kDpdxFine:
case BuiltinType::kDpdy:
case BuiltinType::kDpdyCoarse:
case BuiltinType::kDpdyFine:
case BuiltinType::kExp:
case BuiltinType::kExp2:
case BuiltinType::kFloor:
case BuiltinType::kFract:
case BuiltinType::kFwidth:
case BuiltinType::kFwidthCoarse:
case BuiltinType::kFwidthFine:
case BuiltinType::kInverseSqrt:
case BuiltinType::kIsFinite:
case BuiltinType::kIsInf:
case BuiltinType::kIsNan:
case BuiltinType::kIsNormal:
case BuiltinType::kLength:
case BuiltinType::kLog:
case BuiltinType::kLog2:
case BuiltinType::kNormalize:
case BuiltinType::kRound:
case BuiltinType::kSin:
case BuiltinType::kSinh:
case BuiltinType::kSqrt:
case BuiltinType::kTan:
case BuiltinType::kTanh:
case BuiltinType::kTrunc:
case BuiltinType::kSign:
return builder->Call(str.str(), "f2");
case IntrinsicType::kLdexp:
case BuiltinType::kLdexp:
return builder->Call(str.str(), "f2", "i2");
case IntrinsicType::kAtan2:
case IntrinsicType::kDot:
case IntrinsicType::kDistance:
case IntrinsicType::kPow:
case IntrinsicType::kReflect:
case IntrinsicType::kStep:
case BuiltinType::kAtan2:
case BuiltinType::kDot:
case BuiltinType::kDistance:
case BuiltinType::kPow:
case BuiltinType::kReflect:
case BuiltinType::kStep:
return builder->Call(str.str(), "f2", "f2");
case IntrinsicType::kCross:
case BuiltinType::kCross:
return builder->Call(str.str(), "f3", "f3");
case IntrinsicType::kFma:
case IntrinsicType::kMix:
case IntrinsicType::kFaceForward:
case IntrinsicType::kSmoothStep:
case BuiltinType::kFma:
case BuiltinType::kMix:
case BuiltinType::kFaceForward:
case BuiltinType::kSmoothStep:
return builder->Call(str.str(), "f2", "f2", "f2");
case IntrinsicType::kAll:
case IntrinsicType::kAny:
case BuiltinType::kAll:
case BuiltinType::kAny:
return builder->Call(str.str(), "b2");
case IntrinsicType::kAbs:
case BuiltinType::kAbs:
if (type == ParamType::kF32) {
return builder->Call(str.str(), "f2");
} else {
return builder->Call(str.str(), "u2");
}
case IntrinsicType::kCountOneBits:
case IntrinsicType::kReverseBits:
case BuiltinType::kCountOneBits:
case BuiltinType::kReverseBits:
return builder->Call(str.str(), "u2");
case IntrinsicType::kMax:
case IntrinsicType::kMin:
case BuiltinType::kMax:
case BuiltinType::kMin:
if (type == ParamType::kF32) {
return builder->Call(str.str(), "f2", "f2");
} else {
return builder->Call(str.str(), "u2", "u2");
}
case IntrinsicType::kClamp:
case BuiltinType::kClamp:
if (type == ParamType::kF32) {
return builder->Call(str.str(), "f2", "f2", "f2");
} else {
return builder->Call(str.str(), "u2", "u2", "u2");
}
case IntrinsicType::kSelect:
case BuiltinType::kSelect:
return builder->Call(str.str(), "f2", "f2", "b2");
case IntrinsicType::kDeterminant:
case BuiltinType::kDeterminant:
return builder->Call(str.str(), "m2x2");
case IntrinsicType::kTranspose:
case BuiltinType::kTranspose:
return builder->Call(str.str(), "m3x2");
default:
break;
}
return nullptr;
}
using HlslIntrinsicTest = TestParamHelper<IntrinsicData>;
TEST_P(HlslIntrinsicTest, Emit) {
using HlslBuiltinTest = TestParamHelper<BuiltinData>;
TEST_P(HlslBuiltinTest, Emit) {
auto param = GetParam();
Global("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
@ -165,8 +165,8 @@ TEST_P(HlslIntrinsicTest, Emit) {
Global("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
Global("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
auto* call = GenerateCall(param.intrinsic, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled intrinsic";
auto* call = GenerateCall(param.builtin, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled builtin";
Func("func", {}, ty.void_(), {CallStmt(call)},
{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
@ -176,89 +176,82 @@ TEST_P(HlslIntrinsicTest, Emit) {
ASSERT_NE(sem, nullptr);
auto* target = sem->Target();
ASSERT_NE(target, nullptr);
auto* intrinsic = target->As<sem::Intrinsic>();
ASSERT_NE(intrinsic, nullptr);
auto* builtin = target->As<sem::Builtin>();
ASSERT_NE(builtin, nullptr);
EXPECT_EQ(gen.generate_builtin_name(intrinsic), param.hlsl_name);
EXPECT_EQ(gen.generate_builtin_name(builtin), param.hlsl_name);
}
INSTANTIATE_TEST_SUITE_P(
HlslGeneratorImplTest_Intrinsic,
HlslIntrinsicTest,
HlslGeneratorImplTest_Builtin,
HlslBuiltinTest,
testing::Values(
IntrinsicData{IntrinsicType::kAbs, ParamType::kF32, "abs"},
IntrinsicData{IntrinsicType::kAbs, ParamType::kU32, "abs"},
IntrinsicData{IntrinsicType::kAcos, ParamType::kF32, "acos"},
IntrinsicData{IntrinsicType::kAll, ParamType::kBool, "all"},
IntrinsicData{IntrinsicType::kAny, ParamType::kBool, "any"},
IntrinsicData{IntrinsicType::kAsin, ParamType::kF32, "asin"},
IntrinsicData{IntrinsicType::kAtan, ParamType::kF32, "atan"},
IntrinsicData{IntrinsicType::kAtan2, ParamType::kF32, "atan2"},
IntrinsicData{IntrinsicType::kCeil, ParamType::kF32, "ceil"},
IntrinsicData{IntrinsicType::kClamp, ParamType::kF32, "clamp"},
IntrinsicData{IntrinsicType::kClamp, ParamType::kU32, "clamp"},
IntrinsicData{IntrinsicType::kCos, ParamType::kF32, "cos"},
IntrinsicData{IntrinsicType::kCosh, ParamType::kF32, "cosh"},
IntrinsicData{IntrinsicType::kCountOneBits, ParamType::kU32,
"countbits"},
IntrinsicData{IntrinsicType::kCross, ParamType::kF32, "cross"},
IntrinsicData{IntrinsicType::kDeterminant, ParamType::kF32,
"determinant"},
IntrinsicData{IntrinsicType::kDistance, ParamType::kF32, "distance"},
IntrinsicData{IntrinsicType::kDot, ParamType::kF32, "dot"},
IntrinsicData{IntrinsicType::kDpdx, ParamType::kF32, "ddx"},
IntrinsicData{IntrinsicType::kDpdxCoarse, ParamType::kF32,
"ddx_coarse"},
IntrinsicData{IntrinsicType::kDpdxFine, ParamType::kF32, "ddx_fine"},
IntrinsicData{IntrinsicType::kDpdy, ParamType::kF32, "ddy"},
IntrinsicData{IntrinsicType::kDpdyCoarse, ParamType::kF32,
"ddy_coarse"},
IntrinsicData{IntrinsicType::kDpdyFine, ParamType::kF32, "ddy_fine"},
IntrinsicData{IntrinsicType::kExp, ParamType::kF32, "exp"},
IntrinsicData{IntrinsicType::kExp2, ParamType::kF32, "exp2"},
IntrinsicData{IntrinsicType::kFaceForward, ParamType::kF32,
"faceforward"},
IntrinsicData{IntrinsicType::kFloor, ParamType::kF32, "floor"},
IntrinsicData{IntrinsicType::kFma, ParamType::kF32, "mad"},
IntrinsicData{IntrinsicType::kFract, ParamType::kF32, "frac"},
IntrinsicData{IntrinsicType::kFwidth, ParamType::kF32, "fwidth"},
IntrinsicData{IntrinsicType::kFwidthCoarse, ParamType::kF32, "fwidth"},
IntrinsicData{IntrinsicType::kFwidthFine, ParamType::kF32, "fwidth"},
IntrinsicData{IntrinsicType::kInverseSqrt, ParamType::kF32, "rsqrt"},
IntrinsicData{IntrinsicType::kIsFinite, ParamType::kF32, "isfinite"},
IntrinsicData{IntrinsicType::kIsInf, ParamType::kF32, "isinf"},
IntrinsicData{IntrinsicType::kIsNan, ParamType::kF32, "isnan"},
IntrinsicData{IntrinsicType::kLdexp, ParamType::kF32, "ldexp"},
IntrinsicData{IntrinsicType::kLength, ParamType::kF32, "length"},
IntrinsicData{IntrinsicType::kLog, ParamType::kF32, "log"},
IntrinsicData{IntrinsicType::kLog2, ParamType::kF32, "log2"},
IntrinsicData{IntrinsicType::kMax, ParamType::kF32, "max"},
IntrinsicData{IntrinsicType::kMax, ParamType::kU32, "max"},
IntrinsicData{IntrinsicType::kMin, ParamType::kF32, "min"},
IntrinsicData{IntrinsicType::kMin, ParamType::kU32, "min"},
IntrinsicData{IntrinsicType::kMix, ParamType::kF32, "lerp"},
IntrinsicData{IntrinsicType::kNormalize, ParamType::kF32, "normalize"},
IntrinsicData{IntrinsicType::kPow, ParamType::kF32, "pow"},
IntrinsicData{IntrinsicType::kReflect, ParamType::kF32, "reflect"},
IntrinsicData{IntrinsicType::kReverseBits, ParamType::kU32,
"reversebits"},
IntrinsicData{IntrinsicType::kRound, ParamType::kU32, "round"},
IntrinsicData{IntrinsicType::kSign, ParamType::kF32, "sign"},
IntrinsicData{IntrinsicType::kSin, ParamType::kF32, "sin"},
IntrinsicData{IntrinsicType::kSinh, ParamType::kF32, "sinh"},
IntrinsicData{IntrinsicType::kSmoothStep, ParamType::kF32,
"smoothstep"},
IntrinsicData{IntrinsicType::kSqrt, ParamType::kF32, "sqrt"},
IntrinsicData{IntrinsicType::kStep, ParamType::kF32, "step"},
IntrinsicData{IntrinsicType::kTan, ParamType::kF32, "tan"},
IntrinsicData{IntrinsicType::kTanh, ParamType::kF32, "tanh"},
IntrinsicData{IntrinsicType::kTranspose, ParamType::kF32, "transpose"},
IntrinsicData{IntrinsicType::kTrunc, ParamType::kF32, "trunc"}));
BuiltinData{BuiltinType::kAbs, ParamType::kF32, "abs"},
BuiltinData{BuiltinType::kAbs, ParamType::kU32, "abs"},
BuiltinData{BuiltinType::kAcos, ParamType::kF32, "acos"},
BuiltinData{BuiltinType::kAll, ParamType::kBool, "all"},
BuiltinData{BuiltinType::kAny, ParamType::kBool, "any"},
BuiltinData{BuiltinType::kAsin, ParamType::kF32, "asin"},
BuiltinData{BuiltinType::kAtan, ParamType::kF32, "atan"},
BuiltinData{BuiltinType::kAtan2, ParamType::kF32, "atan2"},
BuiltinData{BuiltinType::kCeil, ParamType::kF32, "ceil"},
BuiltinData{BuiltinType::kClamp, ParamType::kF32, "clamp"},
BuiltinData{BuiltinType::kClamp, ParamType::kU32, "clamp"},
BuiltinData{BuiltinType::kCos, ParamType::kF32, "cos"},
BuiltinData{BuiltinType::kCosh, ParamType::kF32, "cosh"},
BuiltinData{BuiltinType::kCountOneBits, ParamType::kU32, "countbits"},
BuiltinData{BuiltinType::kCross, ParamType::kF32, "cross"},
BuiltinData{BuiltinType::kDeterminant, ParamType::kF32, "determinant"},
BuiltinData{BuiltinType::kDistance, ParamType::kF32, "distance"},
BuiltinData{BuiltinType::kDot, ParamType::kF32, "dot"},
BuiltinData{BuiltinType::kDpdx, ParamType::kF32, "ddx"},
BuiltinData{BuiltinType::kDpdxCoarse, ParamType::kF32, "ddx_coarse"},
BuiltinData{BuiltinType::kDpdxFine, ParamType::kF32, "ddx_fine"},
BuiltinData{BuiltinType::kDpdy, ParamType::kF32, "ddy"},
BuiltinData{BuiltinType::kDpdyCoarse, ParamType::kF32, "ddy_coarse"},
BuiltinData{BuiltinType::kDpdyFine, ParamType::kF32, "ddy_fine"},
BuiltinData{BuiltinType::kExp, ParamType::kF32, "exp"},
BuiltinData{BuiltinType::kExp2, ParamType::kF32, "exp2"},
BuiltinData{BuiltinType::kFaceForward, ParamType::kF32, "faceforward"},
BuiltinData{BuiltinType::kFloor, ParamType::kF32, "floor"},
BuiltinData{BuiltinType::kFma, ParamType::kF32, "mad"},
BuiltinData{BuiltinType::kFract, ParamType::kF32, "frac"},
BuiltinData{BuiltinType::kFwidth, ParamType::kF32, "fwidth"},
BuiltinData{BuiltinType::kFwidthCoarse, ParamType::kF32, "fwidth"},
BuiltinData{BuiltinType::kFwidthFine, ParamType::kF32, "fwidth"},
BuiltinData{BuiltinType::kInverseSqrt, ParamType::kF32, "rsqrt"},
BuiltinData{BuiltinType::kIsFinite, ParamType::kF32, "isfinite"},
BuiltinData{BuiltinType::kIsInf, ParamType::kF32, "isinf"},
BuiltinData{BuiltinType::kIsNan, ParamType::kF32, "isnan"},
BuiltinData{BuiltinType::kLdexp, ParamType::kF32, "ldexp"},
BuiltinData{BuiltinType::kLength, ParamType::kF32, "length"},
BuiltinData{BuiltinType::kLog, ParamType::kF32, "log"},
BuiltinData{BuiltinType::kLog2, ParamType::kF32, "log2"},
BuiltinData{BuiltinType::kMax, ParamType::kF32, "max"},
BuiltinData{BuiltinType::kMax, ParamType::kU32, "max"},
BuiltinData{BuiltinType::kMin, ParamType::kF32, "min"},
BuiltinData{BuiltinType::kMin, ParamType::kU32, "min"},
BuiltinData{BuiltinType::kMix, ParamType::kF32, "lerp"},
BuiltinData{BuiltinType::kNormalize, ParamType::kF32, "normalize"},
BuiltinData{BuiltinType::kPow, ParamType::kF32, "pow"},
BuiltinData{BuiltinType::kReflect, ParamType::kF32, "reflect"},
BuiltinData{BuiltinType::kReverseBits, ParamType::kU32, "reversebits"},
BuiltinData{BuiltinType::kRound, ParamType::kU32, "round"},
BuiltinData{BuiltinType::kSign, ParamType::kF32, "sign"},
BuiltinData{BuiltinType::kSin, ParamType::kF32, "sin"},
BuiltinData{BuiltinType::kSinh, ParamType::kF32, "sinh"},
BuiltinData{BuiltinType::kSmoothStep, ParamType::kF32, "smoothstep"},
BuiltinData{BuiltinType::kSqrt, ParamType::kF32, "sqrt"},
BuiltinData{BuiltinType::kStep, ParamType::kF32, "step"},
BuiltinData{BuiltinType::kTan, ParamType::kF32, "tan"},
BuiltinData{BuiltinType::kTanh, ParamType::kF32, "tanh"},
BuiltinData{BuiltinType::kTranspose, ParamType::kF32, "transpose"},
BuiltinData{BuiltinType::kTrunc, ParamType::kF32, "trunc"}));
TEST_F(HlslGeneratorImplTest_Intrinsic, DISABLED_Intrinsic_IsNormal) {
TEST_F(HlslGeneratorImplTest_Builtin, DISABLED_Builtin_IsNormal) {
FAIL();
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Intrinsic_Call) {
TEST_F(HlslGeneratorImplTest_Builtin, Builtin_Call) {
auto* call = Call("dot", "param1", "param2");
Global("param1", ty.vec3<f32>(), ast::StorageClass::kPrivate);
@ -274,7 +267,7 @@ TEST_F(HlslGeneratorImplTest_Intrinsic, Intrinsic_Call) {
EXPECT_EQ(out.str(), "dot(param1, param2)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Select_Scalar) {
TEST_F(HlslGeneratorImplTest_Builtin, Select_Scalar) {
auto* call = Call("select", 1.0f, 2.0f, true);
WrapInFunction(CallStmt(call));
GeneratorImpl& gen = Build();
@ -285,7 +278,7 @@ TEST_F(HlslGeneratorImplTest_Intrinsic, Select_Scalar) {
EXPECT_EQ(out.str(), "(true ? 2.0f : 1.0f)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Select_Vector) {
TEST_F(HlslGeneratorImplTest_Builtin, Select_Vector) {
auto* call =
Call("select", vec2<i32>(1, 2), vec2<i32>(3, 4), vec2<bool>(true, false));
WrapInFunction(CallStmt(call));
@ -297,7 +290,7 @@ TEST_F(HlslGeneratorImplTest_Intrinsic, Select_Vector) {
EXPECT_EQ(out.str(), "(bool2(true, false) ? int2(3, 4) : int2(1, 2))");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Modf_Scalar) {
TEST_F(HlslGeneratorImplTest_Builtin, Modf_Scalar) {
auto* call = Call("modf", 1.0f);
WrapInFunction(CallStmt(call));
@ -323,7 +316,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Modf_Vector) {
TEST_F(HlslGeneratorImplTest_Builtin, Modf_Vector) {
auto* call = Call("modf", vec3<f32>());
WrapInFunction(CallStmt(call));
@ -349,7 +342,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Frexp_Scalar_i32) {
TEST_F(HlslGeneratorImplTest_Builtin, Frexp_Scalar_i32) {
auto* call = Call("frexp", 1.0f);
WrapInFunction(CallStmt(call));
@ -375,7 +368,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Frexp_Vector_i32) {
TEST_F(HlslGeneratorImplTest_Builtin, Frexp_Vector_i32) {
auto* call = Call("frexp", vec3<f32>());
WrapInFunction(CallStmt(call));
@ -401,7 +394,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, IsNormal_Scalar) {
TEST_F(HlslGeneratorImplTest_Builtin, IsNormal_Scalar) {
auto* val = Var("val", ty.f32());
auto* call = Call("isNormal", val);
WrapInFunction(val, call);
@ -424,7 +417,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, IsNormal_Vector) {
TEST_F(HlslGeneratorImplTest_Builtin, IsNormal_Vector) {
auto* val = Var("val", ty.vec3<f32>());
auto* call = Call("isNormal", val);
WrapInFunction(val, call);
@ -447,7 +440,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Degrees_Scalar) {
TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Scalar) {
auto* val = Var("val", ty.f32());
auto* call = Call("degrees", val);
WrapInFunction(val, call);
@ -468,7 +461,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Degrees_Vector) {
TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Vector) {
auto* val = Var("val", ty.vec3<f32>());
auto* call = Call("degrees", val);
WrapInFunction(val, call);
@ -489,7 +482,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Radians_Scalar) {
TEST_F(HlslGeneratorImplTest_Builtin, Radians_Scalar) {
auto* val = Var("val", ty.f32());
auto* call = Call("radians", val);
WrapInFunction(val, call);
@ -510,7 +503,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Radians_Vector) {
TEST_F(HlslGeneratorImplTest_Builtin, Radians_Vector) {
auto* val = Var("val", ty.vec3<f32>());
auto* call = Call("radians", val);
WrapInFunction(val, call);
@ -531,7 +524,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Pack4x8Snorm) {
TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
auto* call = Call("pack4x8snorm", "p1");
Global("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -553,7 +546,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Pack4x8Unorm) {
TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Unorm) {
auto* call = Call("pack4x8unorm", "p1");
Global("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -575,7 +568,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Pack2x16Snorm) {
TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Snorm) {
auto* call = Call("pack2x16snorm", "p1");
Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -597,7 +590,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Pack2x16Unorm) {
TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Unorm) {
auto* call = Call("pack2x16unorm", "p1");
Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -619,7 +612,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Pack2x16Float) {
TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Float) {
auto* call = Call("pack2x16float", "p1");
Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -641,7 +634,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Unpack4x8Snorm) {
TEST_F(HlslGeneratorImplTest_Builtin, Unpack4x8Snorm) {
auto* call = Call("unpack4x8snorm", "p1");
Global("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -664,7 +657,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Unpack4x8Unorm) {
TEST_F(HlslGeneratorImplTest_Builtin, Unpack4x8Unorm) {
auto* call = Call("unpack4x8unorm", "p1");
Global("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -687,7 +680,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Unpack2x16Snorm) {
TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Snorm) {
auto* call = Call("unpack2x16snorm", "p1");
Global("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -710,7 +703,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Unpack2x16Unorm) {
TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Unorm) {
auto* call = Call("unpack2x16unorm", "p1");
Global("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -733,7 +726,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, Unpack2x16Float) {
TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Float) {
auto* call = Call("unpack2x16float", "p1");
Global("p1", ty.u32(), ast::StorageClass::kPrivate);
WrapInFunction(CallStmt(call));
@ -755,7 +748,7 @@ void test_function() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, StorageBarrier) {
TEST_F(HlslGeneratorImplTest_Builtin, StorageBarrier) {
Func("main", {}, ty.void_(), {CallStmt(Call("storageBarrier"))},
{
Stage(ast::PipelineStage::kCompute),
@ -773,7 +766,7 @@ void main() {
)");
}
TEST_F(HlslGeneratorImplTest_Intrinsic, WorkgroupBarrier) {
TEST_F(HlslGeneratorImplTest_Builtin, WorkgroupBarrier) {
Func("main", {}, ty.void_(), {CallStmt(Call("workgroupBarrier"))},
{
Stage(ast::PipelineStage::kCompute),

View File

@ -13,8 +13,8 @@
// limitations under the License.
#include "gmock/gmock.h"
#include "src/ast/builtin_texture_helper_test.h"
#include "src/ast/call_statement.h"
#include "src/ast/intrinsic_texture_helper_test.h"
#include "src/ast/stage_attribute.h"
#include "src/writer/hlsl/test_helper.h"
@ -34,8 +34,8 @@ struct ExpectedResult {
};
ExpectedResult expected_texture_overload(
ast::intrinsic::test::ValidTextureOverload overload) {
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
ast::builtin::test::ValidTextureOverload overload) {
using ValidTextureOverload = ast::builtin::test::ValidTextureOverload;
switch (overload) {
case ValidTextureOverload::kDimensions1d:
case ValidTextureOverload::kDimensionsStorageWO1d:
@ -361,10 +361,10 @@ ExpectedResult expected_texture_overload(
return "<unmatched texture overload>";
} // NOLINT - Ignore the length of this function
class HlslGeneratorIntrinsicTextureTest
: public TestParamHelper<ast::intrinsic::test::TextureOverloadCase> {};
class HlslGeneratorBuiltinTextureTest
: public TestParamHelper<ast::builtin::test::TextureOverloadCase> {};
TEST_P(HlslGeneratorIntrinsicTextureTest, Call) {
TEST_P(HlslGeneratorBuiltinTextureTest, Call) {
auto param = GetParam();
param.BuildTextureVariable(this);
@ -386,9 +386,9 @@ TEST_P(HlslGeneratorIntrinsicTextureTest, Call) {
}
INSTANTIATE_TEST_SUITE_P(
HlslGeneratorIntrinsicTextureTest,
HlslGeneratorIntrinsicTextureTest,
testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
HlslGeneratorBuiltinTextureTest,
HlslGeneratorBuiltinTextureTest,
testing::ValuesIn(ast::builtin::test::TextureOverloadCase::ValidCases()));
} // namespace
} // namespace hlsl

View File

@ -542,8 +542,8 @@ bool GeneratorImpl::EmitCall(std::ostream& out,
if (auto* func = target->As<sem::Function>()) {
return EmitFunctionCall(out, call, func);
}
if (auto* intrinsic = target->As<sem::Intrinsic>()) {
return EmitIntrinsicCall(out, call, intrinsic);
if (auto* builtin = target->As<sem::Builtin>()) {
return EmitBuiltinCall(out, call, builtin);
}
if (auto* conv = target->As<sem::TypeConversion>()) {
return EmitTypeConversion(out, call, conv);
@ -579,34 +579,34 @@ bool GeneratorImpl::EmitFunctionCall(std::ostream& out,
return true;
}
bool GeneratorImpl::EmitIntrinsicCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic) {
bool GeneratorImpl::EmitBuiltinCall(std::ostream& out,
const sem::Call* call,
const sem::Builtin* builtin) {
auto* expr = call->Declaration();
if (intrinsic->IsAtomic()) {
return EmitAtomicCall(out, expr, intrinsic);
if (builtin->IsAtomic()) {
return EmitAtomicCall(out, expr, builtin);
}
if (intrinsic->IsTexture()) {
return EmitTextureCall(out, call, intrinsic);
if (builtin->IsTexture()) {
return EmitTextureCall(out, call, builtin);
}
auto name = generate_builtin_name(intrinsic);
auto name = generate_builtin_name(builtin);
switch (intrinsic->Type()) {
case sem::IntrinsicType::kDot:
return EmitDotCall(out, expr, intrinsic);
case sem::IntrinsicType::kModf:
return EmitModfCall(out, expr, intrinsic);
case sem::IntrinsicType::kFrexp:
return EmitFrexpCall(out, expr, intrinsic);
case sem::IntrinsicType::kDegrees:
return EmitDegreesCall(out, expr, intrinsic);
case sem::IntrinsicType::kRadians:
return EmitRadiansCall(out, expr, intrinsic);
switch (builtin->Type()) {
case sem::BuiltinType::kDot:
return EmitDotCall(out, expr, builtin);
case sem::BuiltinType::kModf:
return EmitModfCall(out, expr, builtin);
case sem::BuiltinType::kFrexp:
return EmitFrexpCall(out, expr, builtin);
case sem::BuiltinType::kDegrees:
return EmitDegreesCall(out, expr, builtin);
case sem::BuiltinType::kRadians:
return EmitRadiansCall(out, expr, builtin);
case sem::IntrinsicType::kPack2x16float:
case sem::IntrinsicType::kUnpack2x16float: {
if (intrinsic->Type() == sem::IntrinsicType::kPack2x16float) {
case sem::BuiltinType::kPack2x16float:
case sem::BuiltinType::kUnpack2x16float: {
if (builtin->Type() == sem::BuiltinType::kPack2x16float) {
out << "as_type<uint>(half2(";
} else {
out << "float2(as_type<half2>(";
@ -619,16 +619,16 @@ bool GeneratorImpl::EmitIntrinsicCall(std::ostream& out,
}
// TODO(crbug.com/tint/661): Combine sequential barriers to a single
// instruction.
case sem::IntrinsicType::kStorageBarrier: {
case sem::BuiltinType::kStorageBarrier: {
out << "threadgroup_barrier(mem_flags::mem_device)";
return true;
}
case sem::IntrinsicType::kWorkgroupBarrier: {
case sem::BuiltinType::kWorkgroupBarrier: {
out << "threadgroup_barrier(mem_flags::mem_threadgroup)";
return true;
}
case sem::IntrinsicType::kLength: {
case sem::BuiltinType::kLength: {
auto* sem = builder_.Sem().Get(expr->args[0]);
if (sem->Type()->UnwrapRef()->is_scalar()) {
// Emulate scalar overload using fabs(x).
@ -637,7 +637,7 @@ bool GeneratorImpl::EmitIntrinsicCall(std::ostream& out,
break;
}
case sem::IntrinsicType::kDistance: {
case sem::BuiltinType::kDistance: {
auto* sem = builder_.Sem().Get(expr->args[0]);
if (sem->Type()->UnwrapRef()->is_scalar()) {
// Emulate scalar overload using fabs(x - y);
@ -741,7 +741,7 @@ bool GeneratorImpl::EmitTypeConstructor(std::ostream& out,
bool GeneratorImpl::EmitAtomicCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
const sem::Builtin* builtin) {
auto call = [&](const std::string& name, bool append_memory_order_relaxed) {
out << name;
{
@ -762,38 +762,38 @@ bool GeneratorImpl::EmitAtomicCall(std::ostream& out,
return true;
};
switch (intrinsic->Type()) {
case sem::IntrinsicType::kAtomicLoad:
switch (builtin->Type()) {
case sem::BuiltinType::kAtomicLoad:
return call("atomic_load_explicit", true);
case sem::IntrinsicType::kAtomicStore:
case sem::BuiltinType::kAtomicStore:
return call("atomic_store_explicit", true);
case sem::IntrinsicType::kAtomicAdd:
case sem::BuiltinType::kAtomicAdd:
return call("atomic_fetch_add_explicit", true);
case sem::IntrinsicType::kAtomicSub:
case sem::BuiltinType::kAtomicSub:
return call("atomic_fetch_sub_explicit", true);
case sem::IntrinsicType::kAtomicMax:
case sem::BuiltinType::kAtomicMax:
return call("atomic_fetch_max_explicit", true);
case sem::IntrinsicType::kAtomicMin:
case sem::BuiltinType::kAtomicMin:
return call("atomic_fetch_min_explicit", true);
case sem::IntrinsicType::kAtomicAnd:
case sem::BuiltinType::kAtomicAnd:
return call("atomic_fetch_and_explicit", true);
case sem::IntrinsicType::kAtomicOr:
case sem::BuiltinType::kAtomicOr:
return call("atomic_fetch_or_explicit", true);
case sem::IntrinsicType::kAtomicXor:
case sem::BuiltinType::kAtomicXor:
return call("atomic_fetch_xor_explicit", true);
case sem::IntrinsicType::kAtomicExchange:
case sem::BuiltinType::kAtomicExchange:
return call("atomic_exchange_explicit", true);
case sem::IntrinsicType::kAtomicCompareExchangeWeak: {
case sem::BuiltinType::kAtomicCompareExchangeWeak: {
auto* ptr_ty = TypeOf(expr->args[0])->UnwrapRef()->As<sem::Pointer>();
auto sc = ptr_ty->StorageClass();
@ -836,16 +836,16 @@ bool GeneratorImpl::EmitAtomicCall(std::ostream& out,
}
TINT_UNREACHABLE(Writer, diagnostics_)
<< "unsupported atomic intrinsic: " << intrinsic->Type();
<< "unsupported atomic builtin: " << builtin->Type();
return false;
}
bool GeneratorImpl::EmitTextureCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic) {
const sem::Builtin* builtin) {
using Usage = sem::ParameterUsage;
auto& signature = intrinsic->Signature();
auto& signature = builtin->Signature();
auto* expr = call->Declaration();
auto& arguments = call->Arguments();
@ -883,8 +883,8 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
return true;
};
switch (intrinsic->Type()) {
case sem::IntrinsicType::kTextureDimensions: {
switch (builtin->Type()) {
case sem::BuiltinType::kTextureDimensions: {
std::vector<const char*> dims;
switch (texture_type->dim()) {
case ast::TextureDimension::kNone:
@ -936,7 +936,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
}
return true;
}
case sem::IntrinsicType::kTextureNumLayers: {
case sem::BuiltinType::kTextureNumLayers: {
out << "int(";
if (!texture_expr()) {
return false;
@ -944,7 +944,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
out << ".get_array_size())";
return true;
}
case sem::IntrinsicType::kTextureNumLevels: {
case sem::BuiltinType::kTextureNumLevels: {
out << "int(";
if (!texture_expr()) {
return false;
@ -952,7 +952,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
out << ".get_num_mip_levels())";
return true;
}
case sem::IntrinsicType::kTextureNumSamples: {
case sem::BuiltinType::kTextureNumSamples: {
out << "int(";
if (!texture_expr()) {
return false;
@ -970,33 +970,33 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
bool lod_param_is_named = true;
switch (intrinsic->Type()) {
case sem::IntrinsicType::kTextureSample:
case sem::IntrinsicType::kTextureSampleBias:
case sem::IntrinsicType::kTextureSampleLevel:
case sem::IntrinsicType::kTextureSampleGrad:
switch (builtin->Type()) {
case sem::BuiltinType::kTextureSample:
case sem::BuiltinType::kTextureSampleBias:
case sem::BuiltinType::kTextureSampleLevel:
case sem::BuiltinType::kTextureSampleGrad:
out << ".sample(";
break;
case sem::IntrinsicType::kTextureSampleCompare:
case sem::IntrinsicType::kTextureSampleCompareLevel:
case sem::BuiltinType::kTextureSampleCompare:
case sem::BuiltinType::kTextureSampleCompareLevel:
out << ".sample_compare(";
break;
case sem::IntrinsicType::kTextureGather:
case sem::BuiltinType::kTextureGather:
out << ".gather(";
break;
case sem::IntrinsicType::kTextureGatherCompare:
case sem::BuiltinType::kTextureGatherCompare:
out << ".gather_compare(";
break;
case sem::IntrinsicType::kTextureLoad:
case sem::BuiltinType::kTextureLoad:
out << ".read(";
lod_param_is_named = false;
break;
case sem::IntrinsicType::kTextureStore:
case sem::BuiltinType::kTextureStore:
out << ".write(";
break;
default:
TINT_UNREACHABLE(Writer, diagnostics_)
<< "Unhandled texture intrinsic '" << intrinsic->str() << "'";
<< "Unhandled texture builtin '" << builtin->str() << "'";
return false;
}
@ -1066,7 +1066,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
out << ")";
}
}
if (intrinsic->Type() == sem::IntrinsicType::kTextureSampleCompareLevel) {
if (builtin->Type() == sem::BuiltinType::kTextureSampleCompareLevel) {
maybe_write_comma();
out << "level(0)";
}
@ -1154,8 +1154,8 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
bool GeneratorImpl::EmitDotCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
auto* vec_ty = intrinsic->Parameters()[0]->Type()->As<sem::Vector>();
const sem::Builtin* builtin) {
auto* vec_ty = builtin->Parameters()[0]->Type()->As<sem::Vector>();
std::string fn = "dot";
if (vec_ty->type()->is_integer_scalar()) {
// MSL does not have a builtin for dot() with integer vector types.
@ -1201,11 +1201,11 @@ bool GeneratorImpl::EmitDotCall(std::ostream& out,
bool GeneratorImpl::EmitModfCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
auto* ty = intrinsic->Parameters()[0]->Type();
auto* ty = builtin->Parameters()[0]->Type();
auto in = params[0];
std::string width;
@ -1216,7 +1216,7 @@ bool GeneratorImpl::EmitModfCall(std::ostream& out,
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
if (!EmitStructType(&helpers_,
intrinsic->ReturnType()->As<sem::Struct>())) {
builtin->ReturnType()->As<sem::Struct>())) {
return false;
}
@ -1229,11 +1229,11 @@ bool GeneratorImpl::EmitModfCall(std::ostream& out,
bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
auto* ty = intrinsic->Parameters()[0]->Type();
auto* ty = builtin->Parameters()[0]->Type();
auto in = params[0];
std::string width;
@ -1244,7 +1244,7 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
// Emit the builtin return type unique to this overload. This does not
// exist in the AST, so it will not be generated in Generate().
if (!EmitStructType(&helpers_,
intrinsic->ReturnType()->As<sem::Struct>())) {
builtin->ReturnType()->As<sem::Struct>())) {
return false;
}
@ -1257,9 +1257,9 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
bool GeneratorImpl::EmitDegreesCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
line(b) << "return " << params[0] << " * " << std::setprecision(20)
<< sem::kRadToDeg << ";";
@ -1269,9 +1269,9 @@ bool GeneratorImpl::EmitDegreesCall(std::ostream& out,
bool GeneratorImpl::EmitRadiansCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
return CallIntrinsicHelper(
out, expr, intrinsic,
const sem::Builtin* builtin) {
return CallBuiltinHelper(
out, expr, builtin,
[&](TextBuffer* b, const std::vector<std::string>& params) {
line(b) << "return " << params[0] << " * " << std::setprecision(20)
<< sem::kDegToRad << ";";
@ -1279,153 +1279,152 @@ bool GeneratorImpl::EmitRadiansCall(std::ostream& out,
});
}
std::string GeneratorImpl::generate_builtin_name(
const sem::Intrinsic* intrinsic) {
std::string GeneratorImpl::generate_builtin_name(const sem::Builtin* builtin) {
std::string out = "";
switch (intrinsic->Type()) {
case sem::IntrinsicType::kAcos:
case sem::IntrinsicType::kAll:
case sem::IntrinsicType::kAny:
case sem::IntrinsicType::kAsin:
case sem::IntrinsicType::kAtan:
case sem::IntrinsicType::kAtan2:
case sem::IntrinsicType::kCeil:
case sem::IntrinsicType::kCos:
case sem::IntrinsicType::kCosh:
case sem::IntrinsicType::kCross:
case sem::IntrinsicType::kDeterminant:
case sem::IntrinsicType::kDistance:
case sem::IntrinsicType::kDot:
case sem::IntrinsicType::kExp:
case sem::IntrinsicType::kExp2:
case sem::IntrinsicType::kFloor:
case sem::IntrinsicType::kFma:
case sem::IntrinsicType::kFract:
case sem::IntrinsicType::kFrexp:
case sem::IntrinsicType::kLength:
case sem::IntrinsicType::kLdexp:
case sem::IntrinsicType::kLog:
case sem::IntrinsicType::kLog2:
case sem::IntrinsicType::kMix:
case sem::IntrinsicType::kModf:
case sem::IntrinsicType::kNormalize:
case sem::IntrinsicType::kPow:
case sem::IntrinsicType::kReflect:
case sem::IntrinsicType::kRefract:
case sem::IntrinsicType::kSelect:
case sem::IntrinsicType::kSin:
case sem::IntrinsicType::kSinh:
case sem::IntrinsicType::kSqrt:
case sem::IntrinsicType::kStep:
case sem::IntrinsicType::kTan:
case sem::IntrinsicType::kTanh:
case sem::IntrinsicType::kTranspose:
case sem::IntrinsicType::kTrunc:
case sem::IntrinsicType::kSign:
case sem::IntrinsicType::kClamp:
out += intrinsic->str();
switch (builtin->Type()) {
case sem::BuiltinType::kAcos:
case sem::BuiltinType::kAll:
case sem::BuiltinType::kAny:
case sem::BuiltinType::kAsin:
case sem::BuiltinType::kAtan:
case sem::BuiltinType::kAtan2:
case sem::BuiltinType::kCeil:
case sem::BuiltinType::kCos:
case sem::BuiltinType::kCosh:
case sem::BuiltinType::kCross:
case sem::BuiltinType::kDeterminant:
case sem::BuiltinType::kDistance:
case sem::BuiltinType::kDot:
case sem::BuiltinType::kExp:
case sem::BuiltinType::kExp2:
case sem::BuiltinType::kFloor:
case sem::BuiltinType::kFma:
case sem::BuiltinType::kFract:
case sem::BuiltinType::kFrexp:
case sem::BuiltinType::kLength:
case sem::BuiltinType::kLdexp:
case sem::BuiltinType::kLog:
case sem::BuiltinType::kLog2:
case sem::BuiltinType::kMix:
case sem::BuiltinType::kModf:
case sem::BuiltinType::kNormalize:
case sem::BuiltinType::kPow:
case sem::BuiltinType::kReflect:
case sem::BuiltinType::kRefract:
case sem::BuiltinType::kSelect:
case sem::BuiltinType::kSin:
case sem::BuiltinType::kSinh:
case sem::BuiltinType::kSqrt:
case sem::BuiltinType::kStep:
case sem::BuiltinType::kTan:
case sem::BuiltinType::kTanh:
case sem::BuiltinType::kTranspose:
case sem::BuiltinType::kTrunc:
case sem::BuiltinType::kSign:
case sem::BuiltinType::kClamp:
out += builtin->str();
break;
case sem::IntrinsicType::kAbs:
if (intrinsic->ReturnType()->is_float_scalar_or_vector()) {
case sem::BuiltinType::kAbs:
if (builtin->ReturnType()->is_float_scalar_or_vector()) {
out += "fabs";
} else {
out += "abs";
}
break;
case sem::IntrinsicType::kCountOneBits:
case sem::BuiltinType::kCountOneBits:
out += "popcount";
break;
case sem::IntrinsicType::kDpdx:
case sem::IntrinsicType::kDpdxCoarse:
case sem::IntrinsicType::kDpdxFine:
case sem::BuiltinType::kDpdx:
case sem::BuiltinType::kDpdxCoarse:
case sem::BuiltinType::kDpdxFine:
out += "dfdx";
break;
case sem::IntrinsicType::kDpdy:
case sem::IntrinsicType::kDpdyCoarse:
case sem::IntrinsicType::kDpdyFine:
case sem::BuiltinType::kDpdy:
case sem::BuiltinType::kDpdyCoarse:
case sem::BuiltinType::kDpdyFine:
out += "dfdy";
break;
case sem::IntrinsicType::kFwidth:
case sem::IntrinsicType::kFwidthCoarse:
case sem::IntrinsicType::kFwidthFine:
case sem::BuiltinType::kFwidth:
case sem::BuiltinType::kFwidthCoarse:
case sem::BuiltinType::kFwidthFine:
out += "fwidth";
break;
case sem::IntrinsicType::kIsFinite:
case sem::BuiltinType::kIsFinite:
out += "isfinite";
break;
case sem::IntrinsicType::kIsInf:
case sem::BuiltinType::kIsInf:
out += "isinf";
break;
case sem::IntrinsicType::kIsNan:
case sem::BuiltinType::kIsNan:
out += "isnan";
break;
case sem::IntrinsicType::kIsNormal:
case sem::BuiltinType::kIsNormal:
out += "isnormal";
break;
case sem::IntrinsicType::kMax:
if (intrinsic->ReturnType()->is_float_scalar_or_vector()) {
case sem::BuiltinType::kMax:
if (builtin->ReturnType()->is_float_scalar_or_vector()) {
out += "fmax";
} else {
out += "max";
}
break;
case sem::IntrinsicType::kMin:
if (intrinsic->ReturnType()->is_float_scalar_or_vector()) {
case sem::BuiltinType::kMin:
if (builtin->ReturnType()->is_float_scalar_or_vector()) {
out += "fmin";
} else {
out += "min";
}
break;
case sem::IntrinsicType::kFaceForward:
case sem::BuiltinType::kFaceForward:
out += "faceforward";
break;
case sem::IntrinsicType::kPack4x8snorm:
case sem::BuiltinType::kPack4x8snorm:
out += "pack_float_to_snorm4x8";
break;
case sem::IntrinsicType::kPack4x8unorm:
case sem::BuiltinType::kPack4x8unorm:
out += "pack_float_to_unorm4x8";
break;
case sem::IntrinsicType::kPack2x16snorm:
case sem::BuiltinType::kPack2x16snorm:
out += "pack_float_to_snorm2x16";
break;
case sem::IntrinsicType::kPack2x16unorm:
case sem::BuiltinType::kPack2x16unorm:
out += "pack_float_to_unorm2x16";
break;
case sem::IntrinsicType::kReverseBits:
case sem::BuiltinType::kReverseBits:
out += "reverse_bits";
break;
case sem::IntrinsicType::kRound:
case sem::BuiltinType::kRound:
out += "rint";
break;
case sem::IntrinsicType::kSmoothStep:
case sem::BuiltinType::kSmoothStep:
out += "smoothstep";
break;
case sem::IntrinsicType::kInverseSqrt:
case sem::BuiltinType::kInverseSqrt:
out += "rsqrt";
break;
case sem::IntrinsicType::kUnpack4x8snorm:
case sem::BuiltinType::kUnpack4x8snorm:
out += "unpack_snorm4x8_to_float";
break;
case sem::IntrinsicType::kUnpack4x8unorm:
case sem::BuiltinType::kUnpack4x8unorm:
out += "unpack_unorm4x8_to_float";
break;
case sem::IntrinsicType::kUnpack2x16snorm:
case sem::BuiltinType::kUnpack2x16snorm:
out += "unpack_snorm2x16_to_float";
break;
case sem::IntrinsicType::kUnpack2x16unorm:
case sem::BuiltinType::kUnpack2x16unorm:
out += "unpack_unorm2x16_to_float";
break;
case sem::IntrinsicType::kArrayLength:
case sem::BuiltinType::kArrayLength:
diagnostics_.add_error(
diag::System::Writer,
"Unable to translate builtin: " + std::string(intrinsic->str()) +
"Unable to translate builtin: " + std::string(builtin->str()) +
"\nDid you forget to pass array_length_from_uniform generator "
"options?");
return "";
default:
diagnostics_.add_error(
diag::System::Writer,
"Unknown import method: " + std::string(intrinsic->str()));
"Unknown import method: " + std::string(builtin->str()));
return "";
}
return out;
@ -2871,26 +2870,26 @@ GeneratorImpl::SizeAndAlign GeneratorImpl::MslPackedTypeSizeAndAlign(
}
template <typename F>
bool GeneratorImpl::CallIntrinsicHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Intrinsic* intrinsic,
F&& build) {
bool GeneratorImpl::CallBuiltinHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Builtin* builtin,
F&& build) {
// Generate the helper function if it hasn't been created already
auto fn = utils::GetOrCreate(intrinsics_, intrinsic, [&]() -> std::string {
auto fn = utils::GetOrCreate(builtins_, builtin, [&]() -> std::string {
TextBuffer b;
TINT_DEFER(helpers_.Append(b));
auto fn_name =
UniqueIdentifier(std::string("tint_") + sem::str(intrinsic->Type()));
UniqueIdentifier(std::string("tint_") + sem::str(builtin->Type()));
std::vector<std::string> parameter_names;
{
auto decl = line(&b);
if (!EmitTypeAndName(decl, intrinsic->ReturnType(), fn_name)) {
if (!EmitTypeAndName(decl, builtin->ReturnType(), fn_name)) {
return "";
}
{
ScopedParen sp(decl);
for (auto* param : intrinsic->Parameters()) {
for (auto* param : builtin->Parameters()) {
if (!parameter_names.empty()) {
decl << ", ";
}

View File

@ -46,7 +46,7 @@ namespace tint {
// Forward declarations
namespace sem {
class Call;
class Intrinsic;
class Builtin;
class TypeConstructor;
class TypeConversion;
} // namespace sem
@ -143,14 +143,14 @@ class GeneratorImpl : public TextGenerator {
/// @param expr the call expression
/// @returns true if the call expression is emitted
bool EmitCall(std::ostream& out, const ast::CallExpression* expr);
/// Handles generating an intrinsic call expression
/// Handles generating a builtin call expression
/// @param out the output of the expression stream
/// @param call the call expression
/// @param intrinsic the intrinsic being called
/// @param builtin the builtin being called
/// @returns true if the call expression is emitted
bool EmitIntrinsicCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic);
bool EmitBuiltinCall(std::ostream& out,
const sem::Call* call,
const sem::Builtin* builtin);
/// Handles generating a type conversion expression
/// @param out the output of the expression stream
/// @param call the call expression
@ -179,60 +179,60 @@ class GeneratorImpl : public TextGenerator {
/// `atomicMax`, etc)
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the atomic intrinsic
/// @param builtin the semantic information for the atomic builtin
/// @returns true if the call expression is emitted
bool EmitAtomicCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
const sem::Builtin* builtin);
/// Handles generating a call to a texture function (`textureSample`,
/// `textureSampleGrad`, etc)
/// @param out the output of the expression stream
/// @param call the call expression
/// @param intrinsic the semantic information for the texture intrinsic
/// @param builtin the semantic information for the texture builtin
/// @returns true if the call expression is emitted
bool EmitTextureCall(std::ostream& out,
const sem::Call* call,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `dot()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `dot()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitDotCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `modf()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `modf()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitModfCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `frexp()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `frexp()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitFrexpCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `degrees()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `degrees()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitDegreesCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
/// Handles generating a call to the `radians()` intrinsic
const sem::Builtin* builtin);
/// Handles generating a call to the `radians()` builtin
/// @param out the output of the expression stream
/// @param expr the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @returns true if the call expression is emitted
bool EmitRadiansCall(std::ostream& out,
const ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
const sem::Builtin* builtin);
/// Handles a case statement
/// @param stmt the statement
/// @returns true if the statement was emitted successfully
@ -368,9 +368,9 @@ class GeneratorImpl : public TextGenerator {
bool EmitZeroValue(std::ostream& out, const sem::Type* type);
/// Handles generating a builtin name
/// @param intrinsic the semantic info for the intrinsic
/// @param builtin the semantic info for the builtin
/// @returns the name or "" if not valid
std::string generate_builtin_name(const sem::Intrinsic* intrinsic);
std::string generate_builtin_name(const sem::Builtin* builtin);
/// Converts a builtin to an attribute name
/// @param builtin the builtin to convert
@ -392,13 +392,13 @@ class GeneratorImpl : public TextGenerator {
uint32_t align;
};
/// CallIntrinsicHelper will call the intrinsic helper function, creating it
/// if it hasn't been built already. If the intrinsic needs to be built then
/// CallIntrinsicHelper will generate the function signature and will call
/// CallBuiltinHelper will call the builtin helper function, creating it
/// if it hasn't been built already. If the builtin needs to be built then
/// CallBuiltinHelper will generate the function signature and will call
/// `build` to emit the body of the function.
/// @param out the output of the expression stream
/// @param call the call expression
/// @param intrinsic the semantic information for the intrinsic
/// @param builtin the semantic information for the builtin
/// @param build a function with the signature:
/// `bool(TextBuffer* buffer, const std::vector<std::string>& params)`
/// Where:
@ -406,10 +406,10 @@ class GeneratorImpl : public TextGenerator {
/// `params` is the name of all the generated function parameters
/// @returns true if the call expression is emitted
template <typename F>
bool CallIntrinsicHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Intrinsic* intrinsic,
F&& build);
bool CallBuiltinHelper(std::ostream& out,
const ast::CallExpression* call,
const sem::Builtin* builtin,
F&& build);
TextBuffer helpers_; // Helper functions emitted at the top of the output
@ -438,7 +438,7 @@ class GeneratorImpl : public TextGenerator {
/// should be created for that index.
std::unordered_map<std::string, std::vector<uint32_t>> workgroup_allocations_;
std::unordered_map<const sem::Intrinsic*, std::string> intrinsics_;
std::unordered_map<const sem::Builtin*, std::string> builtins_;
std::unordered_map<const sem::Type*, std::string> unary_minus_funcs_;
std::unordered_map<uint32_t, std::string> int_dot_funcs_;
};

View File

@ -21,7 +21,7 @@ namespace writer {
namespace msl {
namespace {
using IntrinsicType = sem::IntrinsicType;
using BuiltinType = sem::BuiltinType;
using MslGeneratorImplTest = TestHelper;
@ -31,12 +31,12 @@ enum class ParamType {
kBool,
};
struct IntrinsicData {
IntrinsicType intrinsic;
struct BuiltinData {
BuiltinType builtin;
ParamType type;
const char* msl_name;
};
inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
out << data.msl_name << "<";
switch (data.type) {
case ParamType::kF32:
@ -53,111 +53,111 @@ inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
return out;
}
const ast::CallExpression* GenerateCall(IntrinsicType intrinsic,
const ast::CallExpression* GenerateCall(BuiltinType builtin,
ParamType type,
ProgramBuilder* builder) {
std::string name;
std::ostringstream str(name);
str << intrinsic;
switch (intrinsic) {
case IntrinsicType::kAcos:
case IntrinsicType::kAsin:
case IntrinsicType::kAtan:
case IntrinsicType::kCeil:
case IntrinsicType::kCos:
case IntrinsicType::kCosh:
case IntrinsicType::kDpdx:
case IntrinsicType::kDpdxCoarse:
case IntrinsicType::kDpdxFine:
case IntrinsicType::kDpdy:
case IntrinsicType::kDpdyCoarse:
case IntrinsicType::kDpdyFine:
case IntrinsicType::kExp:
case IntrinsicType::kExp2:
case IntrinsicType::kFloor:
case IntrinsicType::kFract:
case IntrinsicType::kFwidth:
case IntrinsicType::kFwidthCoarse:
case IntrinsicType::kFwidthFine:
case IntrinsicType::kInverseSqrt:
case IntrinsicType::kIsFinite:
case IntrinsicType::kIsInf:
case IntrinsicType::kIsNan:
case IntrinsicType::kIsNormal:
case IntrinsicType::kLength:
case IntrinsicType::kLog:
case IntrinsicType::kLog2:
case IntrinsicType::kNormalize:
case IntrinsicType::kRound:
case IntrinsicType::kSin:
case IntrinsicType::kSinh:
case IntrinsicType::kSqrt:
case IntrinsicType::kTan:
case IntrinsicType::kTanh:
case IntrinsicType::kTrunc:
case IntrinsicType::kSign:
str << builtin;
switch (builtin) {
case BuiltinType::kAcos:
case BuiltinType::kAsin:
case BuiltinType::kAtan:
case BuiltinType::kCeil:
case BuiltinType::kCos:
case BuiltinType::kCosh:
case BuiltinType::kDpdx:
case BuiltinType::kDpdxCoarse:
case BuiltinType::kDpdxFine:
case BuiltinType::kDpdy:
case BuiltinType::kDpdyCoarse:
case BuiltinType::kDpdyFine:
case BuiltinType::kExp:
case BuiltinType::kExp2:
case BuiltinType::kFloor:
case BuiltinType::kFract:
case BuiltinType::kFwidth:
case BuiltinType::kFwidthCoarse:
case BuiltinType::kFwidthFine:
case BuiltinType::kInverseSqrt:
case BuiltinType::kIsFinite:
case BuiltinType::kIsInf:
case BuiltinType::kIsNan:
case BuiltinType::kIsNormal:
case BuiltinType::kLength:
case BuiltinType::kLog:
case BuiltinType::kLog2:
case BuiltinType::kNormalize:
case BuiltinType::kRound:
case BuiltinType::kSin:
case BuiltinType::kSinh:
case BuiltinType::kSqrt:
case BuiltinType::kTan:
case BuiltinType::kTanh:
case BuiltinType::kTrunc:
case BuiltinType::kSign:
return builder->Call(str.str(), "f2");
case IntrinsicType::kLdexp:
case BuiltinType::kLdexp:
return builder->Call(str.str(), "f2", "i2");
case IntrinsicType::kAtan2:
case IntrinsicType::kDot:
case IntrinsicType::kDistance:
case IntrinsicType::kPow:
case IntrinsicType::kReflect:
case IntrinsicType::kStep:
case BuiltinType::kAtan2:
case BuiltinType::kDot:
case BuiltinType::kDistance:
case BuiltinType::kPow:
case BuiltinType::kReflect:
case BuiltinType::kStep:
return builder->Call(str.str(), "f2", "f2");
case IntrinsicType::kStorageBarrier:
case BuiltinType::kStorageBarrier:
return builder->Call(str.str());
case IntrinsicType::kCross:
case BuiltinType::kCross:
return builder->Call(str.str(), "f3", "f3");
case IntrinsicType::kFma:
case IntrinsicType::kMix:
case IntrinsicType::kFaceForward:
case IntrinsicType::kSmoothStep:
case BuiltinType::kFma:
case BuiltinType::kMix:
case BuiltinType::kFaceForward:
case BuiltinType::kSmoothStep:
return builder->Call(str.str(), "f2", "f2", "f2");
case IntrinsicType::kAll:
case IntrinsicType::kAny:
case BuiltinType::kAll:
case BuiltinType::kAny:
return builder->Call(str.str(), "b2");
case IntrinsicType::kAbs:
case BuiltinType::kAbs:
if (type == ParamType::kF32) {
return builder->Call(str.str(), "f2");
} else {
return builder->Call(str.str(), "u2");
}
case IntrinsicType::kCountOneBits:
case IntrinsicType::kReverseBits:
case BuiltinType::kCountOneBits:
case BuiltinType::kReverseBits:
return builder->Call(str.str(), "u2");
case IntrinsicType::kMax:
case IntrinsicType::kMin:
case BuiltinType::kMax:
case BuiltinType::kMin:
if (type == ParamType::kF32) {
return builder->Call(str.str(), "f2", "f2");
} else {
return builder->Call(str.str(), "u2", "u2");
}
case IntrinsicType::kClamp:
case BuiltinType::kClamp:
if (type == ParamType::kF32) {
return builder->Call(str.str(), "f2", "f2", "f2");
} else {
return builder->Call(str.str(), "u2", "u2", "u2");
}
case IntrinsicType::kSelect:
case BuiltinType::kSelect:
return builder->Call(str.str(), "f2", "f2", "b2");
case IntrinsicType::kDeterminant:
case BuiltinType::kDeterminant:
return builder->Call(str.str(), "m2x2");
case IntrinsicType::kPack2x16snorm:
case IntrinsicType::kPack2x16unorm:
case BuiltinType::kPack2x16snorm:
case BuiltinType::kPack2x16unorm:
return builder->Call(str.str(), "f2");
case IntrinsicType::kPack4x8snorm:
case IntrinsicType::kPack4x8unorm:
case BuiltinType::kPack4x8snorm:
case BuiltinType::kPack4x8unorm:
return builder->Call(str.str(), "f4");
case IntrinsicType::kUnpack4x8snorm:
case IntrinsicType::kUnpack4x8unorm:
case IntrinsicType::kUnpack2x16snorm:
case IntrinsicType::kUnpack2x16unorm:
case BuiltinType::kUnpack4x8snorm:
case BuiltinType::kUnpack4x8unorm:
case BuiltinType::kUnpack2x16snorm:
case BuiltinType::kUnpack2x16unorm:
return builder->Call(str.str(), "u1");
case IntrinsicType::kWorkgroupBarrier:
case BuiltinType::kWorkgroupBarrier:
return builder->Call(str.str());
case IntrinsicType::kTranspose:
case BuiltinType::kTranspose:
return builder->Call(str.str(), "m3x2");
default:
break;
@ -165,8 +165,8 @@ const ast::CallExpression* GenerateCall(IntrinsicType intrinsic,
return nullptr;
}
using MslIntrinsicTest = TestParamHelper<IntrinsicData>;
TEST_P(MslIntrinsicTest, Emit) {
using MslBuiltinTest = TestParamHelper<BuiltinData>;
TEST_P(MslBuiltinTest, Emit) {
auto param = GetParam();
Global("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
@ -179,8 +179,8 @@ TEST_P(MslIntrinsicTest, Emit) {
Global("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
Global("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
auto* call = GenerateCall(param.intrinsic, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled intrinsic";
auto* call = GenerateCall(param.builtin, param.type, this);
ASSERT_NE(nullptr, call) << "Unhandled builtin";
Func("func", {}, ty.void_(), {Ignore(call)},
{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
@ -190,100 +190,95 @@ TEST_P(MslIntrinsicTest, Emit) {
ASSERT_NE(sem, nullptr);
auto* target = sem->Target();
ASSERT_NE(target, nullptr);
auto* intrinsic = target->As<sem::Intrinsic>();
ASSERT_NE(intrinsic, nullptr);
auto* builtin = target->As<sem::Builtin>();
ASSERT_NE(builtin, nullptr);
EXPECT_EQ(gen.generate_builtin_name(intrinsic), param.msl_name);
EXPECT_EQ(gen.generate_builtin_name(builtin), param.msl_name);
}
INSTANTIATE_TEST_SUITE_P(
MslGeneratorImplTest,
MslIntrinsicTest,
MslBuiltinTest,
testing::Values(
IntrinsicData{IntrinsicType::kAbs, ParamType::kF32, "fabs"},
IntrinsicData{IntrinsicType::kAbs, ParamType::kU32, "abs"},
IntrinsicData{IntrinsicType::kAcos, ParamType::kF32, "acos"},
IntrinsicData{IntrinsicType::kAll, ParamType::kBool, "all"},
IntrinsicData{IntrinsicType::kAny, ParamType::kBool, "any"},
IntrinsicData{IntrinsicType::kAsin, ParamType::kF32, "asin"},
IntrinsicData{IntrinsicType::kAtan, ParamType::kF32, "atan"},
IntrinsicData{IntrinsicType::kAtan2, ParamType::kF32, "atan2"},
IntrinsicData{IntrinsicType::kCeil, ParamType::kF32, "ceil"},
IntrinsicData{IntrinsicType::kClamp, ParamType::kF32, "clamp"},
IntrinsicData{IntrinsicType::kClamp, ParamType::kU32, "clamp"},
IntrinsicData{IntrinsicType::kCos, ParamType::kF32, "cos"},
IntrinsicData{IntrinsicType::kCosh, ParamType::kF32, "cosh"},
IntrinsicData{IntrinsicType::kCountOneBits, ParamType::kU32,
"popcount"},
IntrinsicData{IntrinsicType::kCross, ParamType::kF32, "cross"},
IntrinsicData{IntrinsicType::kDeterminant, ParamType::kF32,
"determinant"},
IntrinsicData{IntrinsicType::kDistance, ParamType::kF32, "distance"},
IntrinsicData{IntrinsicType::kDot, ParamType::kF32, "dot"},
IntrinsicData{IntrinsicType::kDpdx, ParamType::kF32, "dfdx"},
IntrinsicData{IntrinsicType::kDpdxCoarse, ParamType::kF32, "dfdx"},
IntrinsicData{IntrinsicType::kDpdxFine, ParamType::kF32, "dfdx"},
IntrinsicData{IntrinsicType::kDpdy, ParamType::kF32, "dfdy"},
IntrinsicData{IntrinsicType::kDpdyCoarse, ParamType::kF32, "dfdy"},
IntrinsicData{IntrinsicType::kDpdyFine, ParamType::kF32, "dfdy"},
IntrinsicData{IntrinsicType::kExp, ParamType::kF32, "exp"},
IntrinsicData{IntrinsicType::kExp2, ParamType::kF32, "exp2"},
IntrinsicData{IntrinsicType::kFaceForward, ParamType::kF32,
"faceforward"},
IntrinsicData{IntrinsicType::kFloor, ParamType::kF32, "floor"},
IntrinsicData{IntrinsicType::kFma, ParamType::kF32, "fma"},
IntrinsicData{IntrinsicType::kFract, ParamType::kF32, "fract"},
IntrinsicData{IntrinsicType::kFwidth, ParamType::kF32, "fwidth"},
IntrinsicData{IntrinsicType::kFwidthCoarse, ParamType::kF32, "fwidth"},
IntrinsicData{IntrinsicType::kFwidthFine, ParamType::kF32, "fwidth"},
IntrinsicData{IntrinsicType::kInverseSqrt, ParamType::kF32, "rsqrt"},
IntrinsicData{IntrinsicType::kIsFinite, ParamType::kF32, "isfinite"},
IntrinsicData{IntrinsicType::kIsInf, ParamType::kF32, "isinf"},
IntrinsicData{IntrinsicType::kIsNan, ParamType::kF32, "isnan"},
IntrinsicData{IntrinsicType::kIsNormal, ParamType::kF32, "isnormal"},
IntrinsicData{IntrinsicType::kLdexp, ParamType::kF32, "ldexp"},
IntrinsicData{IntrinsicType::kLength, ParamType::kF32, "length"},
IntrinsicData{IntrinsicType::kLog, ParamType::kF32, "log"},
IntrinsicData{IntrinsicType::kLog2, ParamType::kF32, "log2"},
IntrinsicData{IntrinsicType::kMax, ParamType::kF32, "fmax"},
IntrinsicData{IntrinsicType::kMax, ParamType::kU32, "max"},
IntrinsicData{IntrinsicType::kMin, ParamType::kF32, "fmin"},
IntrinsicData{IntrinsicType::kMin, ParamType::kU32, "min"},
IntrinsicData{IntrinsicType::kNormalize, ParamType::kF32, "normalize"},
IntrinsicData{IntrinsicType::kPack4x8snorm, ParamType::kF32,
"pack_float_to_snorm4x8"},
IntrinsicData{IntrinsicType::kPack4x8unorm, ParamType::kF32,
"pack_float_to_unorm4x8"},
IntrinsicData{IntrinsicType::kPack2x16snorm, ParamType::kF32,
"pack_float_to_snorm2x16"},
IntrinsicData{IntrinsicType::kPack2x16unorm, ParamType::kF32,
"pack_float_to_unorm2x16"},
IntrinsicData{IntrinsicType::kPow, ParamType::kF32, "pow"},
IntrinsicData{IntrinsicType::kReflect, ParamType::kF32, "reflect"},
IntrinsicData{IntrinsicType::kReverseBits, ParamType::kU32,
"reverse_bits"},
IntrinsicData{IntrinsicType::kRound, ParamType::kU32, "rint"},
IntrinsicData{IntrinsicType::kSelect, ParamType::kF32, "select"},
IntrinsicData{IntrinsicType::kSign, ParamType::kF32, "sign"},
IntrinsicData{IntrinsicType::kSin, ParamType::kF32, "sin"},
IntrinsicData{IntrinsicType::kSinh, ParamType::kF32, "sinh"},
IntrinsicData{IntrinsicType::kSmoothStep, ParamType::kF32,
"smoothstep"},
IntrinsicData{IntrinsicType::kSqrt, ParamType::kF32, "sqrt"},
IntrinsicData{IntrinsicType::kStep, ParamType::kF32, "step"},
IntrinsicData{IntrinsicType::kTan, ParamType::kF32, "tan"},
IntrinsicData{IntrinsicType::kTanh, ParamType::kF32, "tanh"},
IntrinsicData{IntrinsicType::kTranspose, ParamType::kF32, "transpose"},
IntrinsicData{IntrinsicType::kTrunc, ParamType::kF32, "trunc"},
IntrinsicData{IntrinsicType::kUnpack4x8snorm, ParamType::kU32,
"unpack_snorm4x8_to_float"},
IntrinsicData{IntrinsicType::kUnpack4x8unorm, ParamType::kU32,
"unpack_unorm4x8_to_float"},
IntrinsicData{IntrinsicType::kUnpack2x16snorm, ParamType::kU32,
"unpack_snorm2x16_to_float"},
IntrinsicData{IntrinsicType::kUnpack2x16unorm, ParamType::kU32,
"unpack_unorm2x16_to_float"}));
BuiltinData{BuiltinType::kAbs, ParamType::kF32, "fabs"},
BuiltinData{BuiltinType::kAbs, ParamType::kU32, "abs"},
BuiltinData{BuiltinType::kAcos, ParamType::kF32, "acos"},
BuiltinData{BuiltinType::kAll, ParamType::kBool, "all"},
BuiltinData{BuiltinType::kAny, ParamType::kBool, "any"},
BuiltinData{BuiltinType::kAsin, ParamType::kF32, "asin"},
BuiltinData{BuiltinType::kAtan, ParamType::kF32, "atan"},
BuiltinData{BuiltinType::kAtan2, ParamType::kF32, "atan2"},
BuiltinData{BuiltinType::kCeil, ParamType::kF32, "ceil"},
BuiltinData{BuiltinType::kClamp, ParamType::kF32, "clamp"},
BuiltinData{BuiltinType::kClamp, ParamType::kU32, "clamp"},
BuiltinData{BuiltinType::kCos, ParamType::kF32, "cos"},
BuiltinData{BuiltinType::kCosh, ParamType::kF32, "cosh"},
BuiltinData{BuiltinType::kCountOneBits, ParamType::kU32, "popcount"},
BuiltinData{BuiltinType::kCross, ParamType::kF32, "cross"},
BuiltinData{BuiltinType::kDeterminant, ParamType::kF32, "determinant"},
BuiltinData{BuiltinType::kDistance, ParamType::kF32, "distance"},
BuiltinData{BuiltinType::kDot, ParamType::kF32, "dot"},
BuiltinData{BuiltinType::kDpdx, ParamType::kF32, "dfdx"},
BuiltinData{BuiltinType::kDpdxCoarse, ParamType::kF32, "dfdx"},
BuiltinData{BuiltinType::kDpdxFine, ParamType::kF32, "dfdx"},
BuiltinData{BuiltinType::kDpdy, ParamType::kF32, "dfdy"},
BuiltinData{BuiltinType::kDpdyCoarse, ParamType::kF32, "dfdy"},
BuiltinData{BuiltinType::kDpdyFine, ParamType::kF32, "dfdy"},
BuiltinData{BuiltinType::kExp, ParamType::kF32, "exp"},
BuiltinData{BuiltinType::kExp2, ParamType::kF32, "exp2"},
BuiltinData{BuiltinType::kFaceForward, ParamType::kF32, "faceforward"},
BuiltinData{BuiltinType::kFloor, ParamType::kF32, "floor"},
BuiltinData{BuiltinType::kFma, ParamType::kF32, "fma"},
BuiltinData{BuiltinType::kFract, ParamType::kF32, "fract"},
BuiltinData{BuiltinType::kFwidth, ParamType::kF32, "fwidth"},
BuiltinData{BuiltinType::kFwidthCoarse, ParamType::kF32, "fwidth"},
BuiltinData{BuiltinType::kFwidthFine, ParamType::kF32, "fwidth"},
BuiltinData{BuiltinType::kInverseSqrt, ParamType::kF32, "rsqrt"},
BuiltinData{BuiltinType::kIsFinite, ParamType::kF32, "isfinite"},
BuiltinData{BuiltinType::kIsInf, ParamType::kF32, "isinf"},
BuiltinData{BuiltinType::kIsNan, ParamType::kF32, "isnan"},
BuiltinData{BuiltinType::kIsNormal, ParamType::kF32, "isnormal"},
BuiltinData{BuiltinType::kLdexp, ParamType::kF32, "ldexp"},
BuiltinData{BuiltinType::kLength, ParamType::kF32, "length"},
BuiltinData{BuiltinType::kLog, ParamType::kF32, "log"},
BuiltinData{BuiltinType::kLog2, ParamType::kF32, "log2"},
BuiltinData{BuiltinType::kMax, ParamType::kF32, "fmax"},
BuiltinData{BuiltinType::kMax, ParamType::kU32, "max"},
BuiltinData{BuiltinType::kMin, ParamType::kF32, "fmin"},
BuiltinData{BuiltinType::kMin, ParamType::kU32, "min"},
BuiltinData{BuiltinType::kNormalize, ParamType::kF32, "normalize"},
BuiltinData{BuiltinType::kPack4x8snorm, ParamType::kF32,
"pack_float_to_snorm4x8"},
BuiltinData{BuiltinType::kPack4x8unorm, ParamType::kF32,
"pack_float_to_unorm4x8"},
BuiltinData{BuiltinType::kPack2x16snorm, ParamType::kF32,
"pack_float_to_snorm2x16"},
BuiltinData{BuiltinType::kPack2x16unorm, ParamType::kF32,
"pack_float_to_unorm2x16"},
BuiltinData{BuiltinType::kPow, ParamType::kF32, "pow"},
BuiltinData{BuiltinType::kReflect, ParamType::kF32, "reflect"},
BuiltinData{BuiltinType::kReverseBits, ParamType::kU32, "reverse_bits"},
BuiltinData{BuiltinType::kRound, ParamType::kU32, "rint"},
BuiltinData{BuiltinType::kSelect, ParamType::kF32, "select"},
BuiltinData{BuiltinType::kSign, ParamType::kF32, "sign"},
BuiltinData{BuiltinType::kSin, ParamType::kF32, "sin"},
BuiltinData{BuiltinType::kSinh, ParamType::kF32, "sinh"},
BuiltinData{BuiltinType::kSmoothStep, ParamType::kF32, "smoothstep"},
BuiltinData{BuiltinType::kSqrt, ParamType::kF32, "sqrt"},
BuiltinData{BuiltinType::kStep, ParamType::kF32, "step"},
BuiltinData{BuiltinType::kTan, ParamType::kF32, "tan"},
BuiltinData{BuiltinType::kTanh, ParamType::kF32, "tanh"},
BuiltinData{BuiltinType::kTranspose, ParamType::kF32, "transpose"},
BuiltinData{BuiltinType::kTrunc, ParamType::kF32, "trunc"},
BuiltinData{BuiltinType::kUnpack4x8snorm, ParamType::kU32,
"unpack_snorm4x8_to_float"},
BuiltinData{BuiltinType::kUnpack4x8unorm, ParamType::kU32,
"unpack_unorm4x8_to_float"},
BuiltinData{BuiltinType::kUnpack2x16snorm, ParamType::kU32,
"unpack_snorm2x16_to_float"},
BuiltinData{BuiltinType::kUnpack2x16unorm, ParamType::kU32,
"unpack_unorm2x16_to_float"}));
TEST_F(MslGeneratorImplTest, Intrinsic_Call) {
TEST_F(MslGeneratorImplTest, Builtin_Call) {
Global("param1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
Global("param2", ty.vec2<f32>(), ast::StorageClass::kPrivate);

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/builtin_texture_helper_test.h"
#include "src/ast/call_statement.h"
#include "src/ast/intrinsic_texture_helper_test.h"
#include "src/writer/msl/test_helper.h"
namespace tint {
@ -22,8 +22,8 @@ namespace msl {
namespace {
std::string expected_texture_overload(
ast::intrinsic::test::ValidTextureOverload overload) {
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
ast::builtin::test::ValidTextureOverload overload) {
using ValidTextureOverload = ast::builtin::test::ValidTextureOverload;
switch (overload) {
case ValidTextureOverload::kDimensions1d:
case ValidTextureOverload::kDimensionsStorageWO1d:
@ -271,10 +271,10 @@ std::string expected_texture_overload(
return "<unmatched texture overload>";
} // NOLINT - Ignore the length of this function
class MslGeneratorIntrinsicTextureTest
: public TestParamHelper<ast::intrinsic::test::TextureOverloadCase> {};
class MslGeneratorBuiltinTextureTest
: public TestParamHelper<ast::builtin::test::TextureOverloadCase> {};
TEST_P(MslGeneratorIntrinsicTextureTest, Call) {
TEST_P(MslGeneratorBuiltinTextureTest, Call) {
auto param = GetParam();
param.BuildTextureVariable(this);
@ -295,9 +295,9 @@ TEST_P(MslGeneratorIntrinsicTextureTest, Call) {
}
INSTANTIATE_TEST_SUITE_P(
MslGeneratorIntrinsicTextureTest,
MslGeneratorIntrinsicTextureTest,
testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
MslGeneratorBuiltinTextureTest,
MslGeneratorBuiltinTextureTest,
testing::ValuesIn(ast::builtin::test::TextureOverloadCase::ValidCases()));
} // namespace
} // namespace msl

View File

@ -35,7 +35,7 @@ TEST_P(MslImportData_SingleParamTest, FloatScalar) {
auto param = GetParam();
auto* call = Call(param.name, 1.f);
// The resolver will set the intrinsic data for the ident
// The resolver will set the builtin data for the ident
WrapInFunction(call);
GeneratorImpl& gen = Build();
@ -44,10 +44,10 @@ TEST_P(MslImportData_SingleParamTest, FloatScalar) {
ASSERT_NE(sem, nullptr);
auto* target = sem->Target();
ASSERT_NE(target, nullptr);
auto* intrinsic = target->As<sem::Intrinsic>();
ASSERT_NE(intrinsic, nullptr);
auto* builtin = target->As<sem::Builtin>();
ASSERT_NE(builtin, nullptr);
ASSERT_EQ(gen.generate_builtin_name(intrinsic), param.msl_name);
ASSERT_EQ(gen.generate_builtin_name(builtin), param.msl_name);
}
INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest,
MslImportData_SingleParamTest,

View File

@ -25,11 +25,11 @@
#include "src/ast/traverse_expressions.h"
#include "src/sem/array.h"
#include "src/sem/atomic_type.h"
#include "src/sem/builtin.h"
#include "src/sem/call.h"
#include "src/sem/depth_multisampled_texture_type.h"
#include "src/sem/depth_texture_type.h"
#include "src/sem/function.h"
#include "src/sem/intrinsic.h"
#include "src/sem/member_accessor_expression.h"
#include "src/sem/multisampled_texture_type.h"
#include "src/sem/reference_type.h"
@ -62,7 +62,7 @@ namespace writer {
namespace spirv {
namespace {
using IntrinsicType = sem::IntrinsicType;
using BuiltinType = sem::BuiltinType;
const char kGLSLstd450[] = "GLSL.std.450";
@ -109,131 +109,131 @@ const sem::Matrix* GetNestedMatrixType(const sem::Type* type) {
return type->As<sem::Matrix>();
}
uint32_t intrinsic_to_glsl_method(const sem::Intrinsic* intrinsic) {
switch (intrinsic->Type()) {
case IntrinsicType::kAcos:
uint32_t builtin_to_glsl_method(const sem::Builtin* builtin) {
switch (builtin->Type()) {
case BuiltinType::kAcos:
return GLSLstd450Acos;
case IntrinsicType::kAsin:
case BuiltinType::kAsin:
return GLSLstd450Asin;
case IntrinsicType::kAtan:
case BuiltinType::kAtan:
return GLSLstd450Atan;
case IntrinsicType::kAtan2:
case BuiltinType::kAtan2:
return GLSLstd450Atan2;
case IntrinsicType::kCeil:
case BuiltinType::kCeil:
return GLSLstd450Ceil;
case IntrinsicType::kClamp:
if (intrinsic->ReturnType()->is_float_scalar_or_vector()) {
case BuiltinType::kClamp:
if (builtin->ReturnType()->is_float_scalar_or_vector()) {
return GLSLstd450NClamp;
} else if (intrinsic->ReturnType()->is_unsigned_scalar_or_vector()) {
} else if (builtin->ReturnType()->is_unsigned_scalar_or_vector()) {
return GLSLstd450UClamp;
} else {
return GLSLstd450SClamp;
}
case IntrinsicType::kCos:
case BuiltinType::kCos:
return GLSLstd450Cos;
case IntrinsicType::kCosh:
case BuiltinType::kCosh:
return GLSLstd450Cosh;
case IntrinsicType::kCross:
case BuiltinType::kCross:
return GLSLstd450Cross;
case IntrinsicType::kDegrees:
case BuiltinType::kDegrees:
return GLSLstd450Degrees;
case IntrinsicType::kDeterminant:
case BuiltinType::kDeterminant:
return GLSLstd450Determinant;
case IntrinsicType::kDistance:
case BuiltinType::kDistance:
return GLSLstd450Distance;
case IntrinsicType::kExp:
case BuiltinType::kExp:
return GLSLstd450Exp;
case IntrinsicType::kExp2:
case BuiltinType::kExp2:
return GLSLstd450Exp2;
case IntrinsicType::kFaceForward:
case BuiltinType::kFaceForward:
return GLSLstd450FaceForward;
case IntrinsicType::kFloor:
case BuiltinType::kFloor:
return GLSLstd450Floor;
case IntrinsicType::kFma:
case BuiltinType::kFma:
return GLSLstd450Fma;
case IntrinsicType::kFract:
case BuiltinType::kFract:
return GLSLstd450Fract;
case IntrinsicType::kFrexp:
case BuiltinType::kFrexp:
return GLSLstd450FrexpStruct;
case IntrinsicType::kInverseSqrt:
case BuiltinType::kInverseSqrt:
return GLSLstd450InverseSqrt;
case IntrinsicType::kLdexp:
case BuiltinType::kLdexp:
return GLSLstd450Ldexp;
case IntrinsicType::kLength:
case BuiltinType::kLength:
return GLSLstd450Length;
case IntrinsicType::kLog:
case BuiltinType::kLog:
return GLSLstd450Log;
case IntrinsicType::kLog2:
case BuiltinType::kLog2:
return GLSLstd450Log2;
case IntrinsicType::kMax:
if (intrinsic->ReturnType()->is_float_scalar_or_vector()) {
case BuiltinType::kMax:
if (builtin->ReturnType()->is_float_scalar_or_vector()) {
return GLSLstd450NMax;
} else if (intrinsic->ReturnType()->is_unsigned_scalar_or_vector()) {
} else if (builtin->ReturnType()->is_unsigned_scalar_or_vector()) {
return GLSLstd450UMax;
} else {
return GLSLstd450SMax;
}
case IntrinsicType::kMin:
if (intrinsic->ReturnType()->is_float_scalar_or_vector()) {
case BuiltinType::kMin:
if (builtin->ReturnType()->is_float_scalar_or_vector()) {
return GLSLstd450NMin;
} else if (intrinsic->ReturnType()->is_unsigned_scalar_or_vector()) {
} else if (builtin->ReturnType()->is_unsigned_scalar_or_vector()) {
return GLSLstd450UMin;
} else {
return GLSLstd450SMin;
}
case IntrinsicType::kMix:
case BuiltinType::kMix:
return GLSLstd450FMix;
case IntrinsicType::kModf:
case BuiltinType::kModf:
return GLSLstd450ModfStruct;
case IntrinsicType::kNormalize:
case BuiltinType::kNormalize:
return GLSLstd450Normalize;
case IntrinsicType::kPack4x8snorm:
case BuiltinType::kPack4x8snorm:
return GLSLstd450PackSnorm4x8;
case IntrinsicType::kPack4x8unorm:
case BuiltinType::kPack4x8unorm:
return GLSLstd450PackUnorm4x8;
case IntrinsicType::kPack2x16snorm:
case BuiltinType::kPack2x16snorm:
return GLSLstd450PackSnorm2x16;
case IntrinsicType::kPack2x16unorm:
case BuiltinType::kPack2x16unorm:
return GLSLstd450PackUnorm2x16;
case IntrinsicType::kPack2x16float:
case BuiltinType::kPack2x16float:
return GLSLstd450PackHalf2x16;
case IntrinsicType::kPow:
case BuiltinType::kPow:
return GLSLstd450Pow;
case IntrinsicType::kRadians:
case BuiltinType::kRadians:
return GLSLstd450Radians;
case IntrinsicType::kReflect:
case BuiltinType::kReflect:
return GLSLstd450Reflect;
case IntrinsicType::kRefract:
case BuiltinType::kRefract:
return GLSLstd450Refract;
case IntrinsicType::kRound:
case BuiltinType::kRound:
return GLSLstd450RoundEven;
case IntrinsicType::kSign:
case BuiltinType::kSign:
return GLSLstd450FSign;
case IntrinsicType::kSin:
case BuiltinType::kSin:
return GLSLstd450Sin;
case IntrinsicType::kSinh:
case BuiltinType::kSinh:
return GLSLstd450Sinh;
case IntrinsicType::kSmoothStep:
case BuiltinType::kSmoothStep:
return GLSLstd450SmoothStep;
case IntrinsicType::kSqrt:
case BuiltinType::kSqrt:
return GLSLstd450Sqrt;
case IntrinsicType::kStep:
case BuiltinType::kStep:
return GLSLstd450Step;
case IntrinsicType::kTan:
case BuiltinType::kTan:
return GLSLstd450Tan;
case IntrinsicType::kTanh:
case BuiltinType::kTanh:
return GLSLstd450Tanh;
case IntrinsicType::kTrunc:
case BuiltinType::kTrunc:
return GLSLstd450Trunc;
case IntrinsicType::kUnpack4x8snorm:
case BuiltinType::kUnpack4x8snorm:
return GLSLstd450UnpackSnorm4x8;
case IntrinsicType::kUnpack4x8unorm:
case BuiltinType::kUnpack4x8unorm:
return GLSLstd450UnpackUnorm4x8;
case IntrinsicType::kUnpack2x16snorm:
case BuiltinType::kUnpack2x16snorm:
return GLSLstd450UnpackSnorm2x16;
case IntrinsicType::kUnpack2x16unorm:
case BuiltinType::kUnpack2x16unorm:
return GLSLstd450UnpackUnorm2x16;
case IntrinsicType::kUnpack2x16float:
case BuiltinType::kUnpack2x16float:
return GLSLstd450UnpackHalf2x16;
default:
break;
@ -2213,8 +2213,8 @@ uint32_t Builder::GenerateCallExpression(const ast::CallExpression* expr) {
if (auto* func = target->As<sem::Function>()) {
return GenerateFunctionCall(call, func);
}
if (auto* intrinsic = target->As<sem::Intrinsic>()) {
return GenerateIntrinsicCall(call, intrinsic);
if (auto* builtin = target->As<sem::Builtin>()) {
return GenerateBuiltinCall(call, builtin);
}
if (target->IsAnyOf<sem::TypeConversion, sem::TypeConstructor>()) {
return GenerateTypeConstructorOrConversion(call, nullptr);
@ -2264,42 +2264,42 @@ uint32_t Builder::GenerateFunctionCall(const sem::Call* call,
return result_id;
}
uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
const sem::Intrinsic* intrinsic) {
uint32_t Builder::GenerateBuiltinCall(const sem::Call* call,
const sem::Builtin* builtin) {
auto result = result_op();
auto result_id = result.to_i();
auto result_type_id = GenerateTypeIfNeeded(intrinsic->ReturnType());
auto result_type_id = GenerateTypeIfNeeded(builtin->ReturnType());
if (result_type_id == 0) {
return 0;
}
if (intrinsic->IsFineDerivative() || intrinsic->IsCoarseDerivative()) {
if (builtin->IsFineDerivative() || builtin->IsCoarseDerivative()) {
push_capability(SpvCapabilityDerivativeControl);
}
if (intrinsic->IsImageQuery()) {
if (builtin->IsImageQuery()) {
push_capability(SpvCapabilityImageQuery);
}
if (intrinsic->IsTexture()) {
if (!GenerateTextureIntrinsic(call, intrinsic, Operand::Int(result_type_id),
result)) {
if (builtin->IsTexture()) {
if (!GenerateTextureBuiltin(call, builtin, Operand::Int(result_type_id),
result)) {
return 0;
}
return result_id;
}
if (intrinsic->IsBarrier()) {
if (!GenerateControlBarrierIntrinsic(intrinsic)) {
if (builtin->IsBarrier()) {
if (!GenerateControlBarrierBuiltin(builtin)) {
return 0;
}
return result_id;
}
if (intrinsic->IsAtomic()) {
if (!GenerateAtomicIntrinsic(call, intrinsic, Operand::Int(result_type_id),
result)) {
if (builtin->IsAtomic()) {
if (!GenerateAtomicBuiltin(call, builtin, Operand::Int(result_type_id),
result)) {
return 0;
}
return result_id;
@ -2310,7 +2310,7 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
auto get_arg_as_value_id = [&](size_t i,
bool generate_load = true) -> uint32_t {
auto* arg = call->Arguments()[i];
auto* param = intrinsic->Parameters()[i];
auto* param = builtin->Parameters()[i];
auto val_id = GenerateExpression(arg->Declaration());
if (val_id == 0) {
return 0;
@ -2334,22 +2334,22 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
op = spv::Op::OpExtInst;
};
switch (intrinsic->Type()) {
case IntrinsicType::kAny:
if (intrinsic->Parameters()[0]->Type()->Is<sem::Bool>()) {
switch (builtin->Type()) {
case BuiltinType::kAny:
if (builtin->Parameters()[0]->Type()->Is<sem::Bool>()) {
// any(v: bool) just resolves to v.
return get_arg_as_value_id(0);
}
op = spv::Op::OpAny;
break;
case IntrinsicType::kAll:
if (intrinsic->Parameters()[0]->Type()->Is<sem::Bool>()) {
case BuiltinType::kAll:
if (builtin->Parameters()[0]->Type()->Is<sem::Bool>()) {
// all(v: bool) just resolves to v.
return get_arg_as_value_id(0);
}
op = spv::Op::OpAll;
break;
case IntrinsicType::kArrayLength: {
case BuiltinType::kArrayLength: {
auto* address_of =
call->Arguments()[0]->Declaration()->As<ast::UnaryOpExpression>();
if (!address_of || address_of->op != ast::UnaryOp::kAddressOf) {
@ -2388,12 +2388,12 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
}
return result_id;
}
case IntrinsicType::kCountOneBits:
case BuiltinType::kCountOneBits:
op = spv::Op::OpBitCount;
break;
case IntrinsicType::kDot: {
case BuiltinType::kDot: {
op = spv::Op::OpDot;
auto* vec_ty = intrinsic->Parameters()[0]->Type()->As<sem::Vector>();
auto* vec_ty = builtin->Parameters()[0]->Type()->As<sem::Vector>();
if (vec_ty->type()->is_integer_scalar()) {
// TODO(crbug.com/tint/1267): OpDot requires floating-point types, but
// WGSL also supports integer types. SPV_KHR_integer_dot_product adds
@ -2433,40 +2433,40 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
}
break;
}
case IntrinsicType::kDpdx:
case BuiltinType::kDpdx:
op = spv::Op::OpDPdx;
break;
case IntrinsicType::kDpdxCoarse:
case BuiltinType::kDpdxCoarse:
op = spv::Op::OpDPdxCoarse;
break;
case IntrinsicType::kDpdxFine:
case BuiltinType::kDpdxFine:
op = spv::Op::OpDPdxFine;
break;
case IntrinsicType::kDpdy:
case BuiltinType::kDpdy:
op = spv::Op::OpDPdy;
break;
case IntrinsicType::kDpdyCoarse:
case BuiltinType::kDpdyCoarse:
op = spv::Op::OpDPdyCoarse;
break;
case IntrinsicType::kDpdyFine:
case BuiltinType::kDpdyFine:
op = spv::Op::OpDPdyFine;
break;
case IntrinsicType::kFwidth:
case BuiltinType::kFwidth:
op = spv::Op::OpFwidth;
break;
case IntrinsicType::kFwidthCoarse:
case BuiltinType::kFwidthCoarse:
op = spv::Op::OpFwidthCoarse;
break;
case IntrinsicType::kFwidthFine:
case BuiltinType::kFwidthFine:
op = spv::Op::OpFwidthFine;
break;
case IntrinsicType::kIsInf:
case BuiltinType::kIsInf:
op = spv::Op::OpIsInf;
break;
case IntrinsicType::kIsNan:
case BuiltinType::kIsNan:
op = spv::Op::OpIsNan;
break;
case IntrinsicType::kIsFinite: {
case BuiltinType::kIsFinite: {
// Implemented as: not(IsInf or IsNan)
auto val_id = get_arg_as_value_id(0);
if (!val_id) {
@ -2492,7 +2492,7 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
}
return 0;
}
case IntrinsicType::kIsNormal: {
case BuiltinType::kIsNormal: {
// A normal number is finite, non-zero, and not subnormal.
// Its exponent is neither of the extreme possible values.
// Implemented as:
@ -2520,7 +2520,7 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
GenerateConstantIfNeeded(ScalarConstant::U32(kMinNormalExponent));
auto max_exponent_id =
GenerateConstantIfNeeded(ScalarConstant::U32(kMaxNormalExponent));
if (auto* fvec_ty = intrinsic->ReturnType()->As<sem::Vector>()) {
if (auto* fvec_ty = builtin->ReturnType()->As<sem::Vector>()) {
// In the vector case, update the unsigned type to a vector type of the
// same size, and create vector constants by replicating the scalars.
// I expect backend compilers to fold these into unique constants, so
@ -2570,7 +2570,7 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
}
return 0;
}
case IntrinsicType::kMix: {
case BuiltinType::kMix: {
auto std450 = Operand::Int(GetGLSLstd450Import());
auto a_id = get_arg_as_value_id(0);
@ -2582,10 +2582,9 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
// If the interpolant is scalar but the objects are vectors, we need to
// splat the interpolant into a vector of the same size.
auto* result_vector_type = intrinsic->ReturnType()->As<sem::Vector>();
if (result_vector_type &&
intrinsic->Parameters()[2]->Type()->is_scalar()) {
f_id = GenerateSplat(f_id, intrinsic->Parameters()[0]->Type());
auto* result_vector_type = builtin->ReturnType()->As<sem::Vector>();
if (result_vector_type && builtin->Parameters()[2]->Type()->is_scalar()) {
f_id = GenerateSplat(f_id, builtin->Parameters()[0]->Type());
if (f_id == 0) {
return 0;
}
@ -2599,10 +2598,10 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
}
return result_id;
}
case IntrinsicType::kReverseBits:
case BuiltinType::kReverseBits:
op = spv::Op::OpBitReverse;
break;
case IntrinsicType::kSelect: {
case BuiltinType::kSelect: {
// Note: Argument order is different in WGSL and SPIR-V
auto cond_id = get_arg_as_value_id(2);
auto true_id = get_arg_as_value_id(1);
@ -2614,9 +2613,8 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
// If the condition is scalar but the objects are vectors, we need to
// splat the condition into a vector of the same size.
// TODO(jrprice): If we're targeting SPIR-V 1.4, we don't need to do this.
auto* result_vector_type = intrinsic->ReturnType()->As<sem::Vector>();
if (result_vector_type &&
intrinsic->Parameters()[2]->Type()->is_scalar()) {
auto* result_vector_type = builtin->ReturnType()->As<sem::Vector>();
if (result_vector_type && builtin->Parameters()[2]->Type()->is_scalar()) {
auto* bool_vec_ty = builder_.create<sem::Vector>(
builder_.create<sem::Bool>(), result_vector_type->Width());
if (!GenerateTypeIfNeeded(bool_vec_ty)) {
@ -2636,25 +2634,25 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
}
return result_id;
}
case IntrinsicType::kTranspose:
case BuiltinType::kTranspose:
op = spv::Op::OpTranspose;
break;
case IntrinsicType::kAbs:
if (intrinsic->ReturnType()->is_unsigned_scalar_or_vector()) {
case BuiltinType::kAbs:
if (builtin->ReturnType()->is_unsigned_scalar_or_vector()) {
// abs() only operates on *signed* integers.
// This is a no-op for unsigned integers.
return get_arg_as_value_id(0);
}
if (intrinsic->ReturnType()->is_float_scalar_or_vector()) {
if (builtin->ReturnType()->is_float_scalar_or_vector()) {
glsl_std450(GLSLstd450FAbs);
} else {
glsl_std450(GLSLstd450SAbs);
}
break;
default: {
auto inst_id = intrinsic_to_glsl_method(intrinsic);
auto inst_id = builtin_to_glsl_method(builtin);
if (inst_id == 0) {
error_ = "unknown method " + std::string(intrinsic->str());
error_ = "unknown method " + std::string(builtin->str());
return 0;
}
glsl_std450(inst_id);
@ -2663,8 +2661,7 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
}
if (op == spv::Op::OpNop) {
error_ =
"unable to determine operator for: " + std::string(intrinsic->str());
error_ = "unable to determine operator for: " + std::string(builtin->str());
return 0;
}
@ -2683,13 +2680,13 @@ uint32_t Builder::GenerateIntrinsicCall(const sem::Call* call,
return result_id;
}
bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
const sem::Intrinsic* intrinsic,
Operand result_type,
Operand result_id) {
bool Builder::GenerateTextureBuiltin(const sem::Call* call,
const sem::Builtin* builtin,
Operand result_type,
Operand result_id) {
using Usage = sem::ParameterUsage;
auto& signature = intrinsic->Signature();
auto& signature = builtin->Signature();
auto& arguments = call->Arguments();
// Generates the given expression, returning the operand ID
@ -2723,7 +2720,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
auto op = spv::Op::OpNop;
// Custom function to call after the texture-intrinsic op has been generated.
// Custom function to call after the texture-builtin op has been generated.
std::function<bool()> post_emission = [] { return true; };
// Populate the spirv_params with common parameters
@ -2848,8 +2845,8 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
return append_coords_to_spirv_params();
};
switch (intrinsic->Type()) {
case IntrinsicType::kTextureDimensions: {
switch (builtin->Type()) {
case BuiltinType::kTextureDimensions: {
// Number of returned elements from OpImageQuerySize[Lod] may not match
// those of textureDimensions().
// This might be due to an extra vector scalar describing the number of
@ -2896,7 +2893,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
}
break;
}
case IntrinsicType::kTextureNumLayers: {
case BuiltinType::kTextureNumLayers: {
uint32_t spirv_dims = 0;
switch (texture_type->dim()) {
default:
@ -2928,19 +2925,19 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
}
break;
}
case IntrinsicType::kTextureNumLevels: {
case BuiltinType::kTextureNumLevels: {
op = spv::Op::OpImageQueryLevels;
append_result_type_and_id_to_spirv_params();
spirv_params.emplace_back(gen_arg(Usage::kTexture));
break;
}
case IntrinsicType::kTextureNumSamples: {
case BuiltinType::kTextureNumSamples: {
op = spv::Op::OpImageQuerySamples;
append_result_type_and_id_to_spirv_params();
spirv_params.emplace_back(gen_arg(Usage::kTexture));
break;
}
case IntrinsicType::kTextureLoad: {
case BuiltinType::kTextureLoad: {
op = texture_type->Is<sem::StorageTexture>() ? spv::Op::OpImageRead
: spv::Op::OpImageFetch;
append_result_type_and_id_to_spirv_params_for_read();
@ -2961,7 +2958,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
break;
}
case IntrinsicType::kTextureStore: {
case BuiltinType::kTextureStore: {
op = spv::Op::OpImageWrite;
spirv_params.emplace_back(gen_arg(Usage::kTexture));
if (!append_coords_to_spirv_params()) {
@ -2970,7 +2967,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
spirv_params.emplace_back(gen_arg(Usage::kValue));
break;
}
case IntrinsicType::kTextureGather: {
case BuiltinType::kTextureGather: {
op = spv::Op::OpImageGather;
append_result_type_and_id_to_spirv_params();
if (!append_image_and_coords_to_spirv_params()) {
@ -2984,7 +2981,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
}
break;
}
case IntrinsicType::kTextureGatherCompare: {
case BuiltinType::kTextureGatherCompare: {
op = spv::Op::OpImageDrefGather;
append_result_type_and_id_to_spirv_params();
if (!append_image_and_coords_to_spirv_params()) {
@ -2993,7 +2990,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
spirv_params.emplace_back(gen_arg(Usage::kDepthRef));
break;
}
case IntrinsicType::kTextureSample: {
case BuiltinType::kTextureSample: {
op = spv::Op::OpImageSampleImplicitLod;
append_result_type_and_id_to_spirv_params_for_read();
if (!append_image_and_coords_to_spirv_params()) {
@ -3001,7 +2998,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
}
break;
}
case IntrinsicType::kTextureSampleBias: {
case BuiltinType::kTextureSampleBias: {
op = spv::Op::OpImageSampleImplicitLod;
append_result_type_and_id_to_spirv_params_for_read();
if (!append_image_and_coords_to_spirv_params()) {
@ -3011,7 +3008,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
ImageOperand{SpvImageOperandsBiasMask, gen_arg(Usage::kBias)});
break;
}
case IntrinsicType::kTextureSampleLevel: {
case BuiltinType::kTextureSampleLevel: {
op = spv::Op::OpImageSampleExplicitLod;
append_result_type_and_id_to_spirv_params_for_read();
if (!append_image_and_coords_to_spirv_params()) {
@ -3037,7 +3034,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
image_operands.emplace_back(ImageOperand{SpvImageOperandsLodMask, level});
break;
}
case IntrinsicType::kTextureSampleGrad: {
case BuiltinType::kTextureSampleGrad: {
op = spv::Op::OpImageSampleExplicitLod;
append_result_type_and_id_to_spirv_params_for_read();
if (!append_image_and_coords_to_spirv_params()) {
@ -3049,7 +3046,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
ImageOperand{SpvImageOperandsGradMask, gen_arg(Usage::kDdy)});
break;
}
case IntrinsicType::kTextureSampleCompare: {
case BuiltinType::kTextureSampleCompare: {
op = spv::Op::OpImageSampleDrefImplicitLod;
append_result_type_and_id_to_spirv_params();
if (!append_image_and_coords_to_spirv_params()) {
@ -3058,7 +3055,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
spirv_params.emplace_back(gen_arg(Usage::kDepthRef));
break;
}
case IntrinsicType::kTextureSampleCompareLevel: {
case BuiltinType::kTextureSampleCompareLevel: {
op = spv::Op::OpImageSampleDrefExplicitLod;
append_result_type_and_id_to_spirv_params();
if (!append_image_and_coords_to_spirv_params()) {
@ -3096,8 +3093,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
}
if (op == spv::Op::OpNop) {
error_ =
"unable to determine operator for: " + std::string(intrinsic->str());
error_ = "unable to determine operator for: " + std::string(builtin->str());
return false;
}
@ -3108,7 +3104,7 @@ bool Builder::GenerateTextureIntrinsic(const sem::Call* call,
return post_emission();
}
bool Builder::GenerateControlBarrierIntrinsic(const sem::Intrinsic* intrinsic) {
bool Builder::GenerateControlBarrierBuiltin(const sem::Builtin* builtin) {
auto const op = spv::Op::OpControlBarrier;
uint32_t execution = 0;
uint32_t memory = 0;
@ -3116,21 +3112,21 @@ bool Builder::GenerateControlBarrierIntrinsic(const sem::Intrinsic* intrinsic) {
// TODO(crbug.com/tint/661): Combine sequential barriers to a single
// instruction.
if (intrinsic->Type() == sem::IntrinsicType::kWorkgroupBarrier) {
if (builtin->Type() == sem::BuiltinType::kWorkgroupBarrier) {
execution = static_cast<uint32_t>(spv::Scope::Workgroup);
memory = static_cast<uint32_t>(spv::Scope::Workgroup);
semantics =
static_cast<uint32_t>(spv::MemorySemanticsMask::AcquireRelease) |
static_cast<uint32_t>(spv::MemorySemanticsMask::WorkgroupMemory);
} else if (intrinsic->Type() == sem::IntrinsicType::kStorageBarrier) {
} else if (builtin->Type() == sem::BuiltinType::kStorageBarrier) {
execution = static_cast<uint32_t>(spv::Scope::Workgroup);
memory = static_cast<uint32_t>(spv::Scope::Workgroup);
semantics =
static_cast<uint32_t>(spv::MemorySemanticsMask::AcquireRelease) |
static_cast<uint32_t>(spv::MemorySemanticsMask::UniformMemory);
} else {
error_ = "unexpected barrier intrinsic type ";
error_ += sem::str(intrinsic->Type());
error_ = "unexpected barrier builtin type ";
error_ += sem::str(builtin->Type());
return false;
}
@ -3148,20 +3144,20 @@ bool Builder::GenerateControlBarrierIntrinsic(const sem::Intrinsic* intrinsic) {
});
}
bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
const sem::Intrinsic* intrinsic,
Operand result_type,
Operand result_id) {
bool Builder::GenerateAtomicBuiltin(const sem::Call* call,
const sem::Builtin* builtin,
Operand result_type,
Operand result_id) {
auto is_value_signed = [&] {
return intrinsic->Parameters()[1]->Type()->Is<sem::I32>();
return builtin->Parameters()[1]->Type()->Is<sem::I32>();
};
auto storage_class =
intrinsic->Parameters()[0]->Type()->As<sem::Pointer>()->StorageClass();
builtin->Parameters()[0]->Type()->As<sem::Pointer>()->StorageClass();
uint32_t memory_id = 0;
switch (
intrinsic->Parameters()[0]->Type()->As<sem::Pointer>()->StorageClass()) {
builtin->Parameters()[0]->Type()->As<sem::Pointer>()->StorageClass()) {
case ast::StorageClass::kWorkgroup:
memory_id = GenerateConstantIfNeeded(
ScalarConstant::U32(static_cast<uint32_t>(spv::Scope::Workgroup)));
@ -3203,8 +3199,8 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
Operand memory = Operand::Int(memory_id);
Operand semantics = Operand::Int(semantics_id);
switch (intrinsic->Type()) {
case sem::IntrinsicType::kAtomicLoad:
switch (builtin->Type()) {
case sem::BuiltinType::kAtomicLoad:
return push_function_inst(spv::Op::OpAtomicLoad, {
result_type,
result_id,
@ -3212,14 +3208,14 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
memory,
semantics,
});
case sem::IntrinsicType::kAtomicStore:
case sem::BuiltinType::kAtomicStore:
return push_function_inst(spv::Op::OpAtomicStore, {
pointer,
memory,
semantics,
value,
});
case sem::IntrinsicType::kAtomicAdd:
case sem::BuiltinType::kAtomicAdd:
return push_function_inst(spv::Op::OpAtomicIAdd, {
result_type,
result_id,
@ -3228,7 +3224,7 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
semantics,
value,
});
case sem::IntrinsicType::kAtomicSub:
case sem::BuiltinType::kAtomicSub:
return push_function_inst(spv::Op::OpAtomicISub, {
result_type,
result_id,
@ -3237,7 +3233,7 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
semantics,
value,
});
case sem::IntrinsicType::kAtomicMax:
case sem::BuiltinType::kAtomicMax:
return push_function_inst(
is_value_signed() ? spv::Op::OpAtomicSMax : spv::Op::OpAtomicUMax,
{
@ -3248,7 +3244,7 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
semantics,
value,
});
case sem::IntrinsicType::kAtomicMin:
case sem::BuiltinType::kAtomicMin:
return push_function_inst(
is_value_signed() ? spv::Op::OpAtomicSMin : spv::Op::OpAtomicUMin,
{
@ -3259,7 +3255,7 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
semantics,
value,
});
case sem::IntrinsicType::kAtomicAnd:
case sem::BuiltinType::kAtomicAnd:
return push_function_inst(spv::Op::OpAtomicAnd, {
result_type,
result_id,
@ -3268,7 +3264,7 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
semantics,
value,
});
case sem::IntrinsicType::kAtomicOr:
case sem::BuiltinType::kAtomicOr:
return push_function_inst(spv::Op::OpAtomicOr, {
result_type,
result_id,
@ -3277,7 +3273,7 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
semantics,
value,
});
case sem::IntrinsicType::kAtomicXor:
case sem::BuiltinType::kAtomicXor:
return push_function_inst(spv::Op::OpAtomicXor, {
result_type,
result_id,
@ -3286,7 +3282,7 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
semantics,
value,
});
case sem::IntrinsicType::kAtomicExchange:
case sem::BuiltinType::kAtomicExchange:
return push_function_inst(spv::Op::OpAtomicExchange, {
result_type,
result_id,
@ -3295,7 +3291,7 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
semantics,
value,
});
case sem::IntrinsicType::kAtomicCompareExchangeWeak: {
case sem::BuiltinType::kAtomicCompareExchangeWeak: {
auto comparator = GenerateExpression(call->Arguments()[1]->Declaration());
if (comparator == 0) {
return false;
@ -3383,7 +3379,7 @@ bool Builder::GenerateAtomicIntrinsic(const sem::Call* call,
}
default:
TINT_UNREACHABLE(Writer, builder_.Diagnostics())
<< "unhandled atomic intrinsic " << intrinsic->Type();
<< "unhandled atomic builtin " << builtin->Type();
return false;
}
}

View File

@ -35,7 +35,7 @@
#include "src/ast/variable_decl_statement.h"
#include "src/program_builder.h"
#include "src/scope_stack.h"
#include "src/sem/intrinsic.h"
#include "src/sem/builtin.h"
#include "src/sem/storage_texture_type.h"
#include "src/writer/spirv/function.h"
#include "src/writer/spirv/scalar_constant.h"
@ -376,44 +376,44 @@ class Builder {
/// @returns the expression ID on success or 0 otherwise
uint32_t GenerateFunctionCall(const sem::Call* call,
const sem::Function* function);
/// Handles generating an intrinsic call expression
/// Handles generating a builtin call expression
/// @param call the call expression
/// @param intrinsic the intrinsic being called
/// @param builtin the builtin being called
/// @returns the expression ID on success or 0 otherwise
uint32_t GenerateIntrinsicCall(const sem::Call* call,
const sem::Intrinsic* intrinsic);
uint32_t GenerateBuiltinCall(const sem::Call* call,
const sem::Builtin* builtin);
/// Handles generating a type constructor or type conversion expression
/// @param call the call expression
/// @param var the variable that is being initialized. May be null.
/// @returns the expression ID on success or 0 otherwise
uint32_t GenerateTypeConstructorOrConversion(const sem::Call* call,
const ast::Variable* var);
/// Generates a texture intrinsic call. Emits an error and returns false if
/// Generates a texture builtin call. Emits an error and returns false if
/// we're currently outside a function.
/// @param call the call expression
/// @param intrinsic the semantic information for the texture intrinsic
/// @param builtin the semantic information for the texture builtin
/// @param result_type result type operand of the texture instruction
/// @param result_id result identifier operand of the texture instruction
/// parameters
/// @returns true on success
bool GenerateTextureIntrinsic(const sem::Call* call,
const sem::Intrinsic* intrinsic,
spirv::Operand result_type,
spirv::Operand result_id);
bool GenerateTextureBuiltin(const sem::Call* call,
const sem::Builtin* builtin,
spirv::Operand result_type,
spirv::Operand result_id);
/// Generates a control barrier statement.
/// @param intrinsic the semantic information for the barrier intrinsic call
/// @param builtin the semantic information for the barrier builtin call
/// @returns true on success
bool GenerateControlBarrierIntrinsic(const sem::Intrinsic* intrinsic);
/// Generates an atomic intrinsic call.
bool GenerateControlBarrierBuiltin(const sem::Builtin* builtin);
/// Generates an atomic builtin call.
/// @param call the call expression
/// @param intrinsic the semantic information for the atomic intrinsic call
/// @param builtin the semantic information for the atomic builtin call
/// @param result_type result type operand of the texture instruction
/// @param result_id result identifier operand of the texture instruction
/// @returns true on success
bool GenerateAtomicIntrinsic(const sem::Call* call,
const sem::Intrinsic* intrinsic,
Operand result_type,
Operand result_id);
bool GenerateAtomicBuiltin(const sem::Call* call,
const sem::Builtin* builtin,
Operand result_type,
Operand result_id);
/// Generates a sampled image
/// @param texture_type the texture type
/// @param texture_operand the texture operand

View File

@ -25,22 +25,22 @@ namespace writer {
namespace spirv {
namespace {
using IntrinsicBuilderTest = TestHelper;
using BuiltinBuilderTest = TestHelper;
template <typename T>
using IntrinsicBuilderTestWithParam = TestParamHelper<T>;
using BuiltinBuilderTestWithParam = TestParamHelper<T>;
struct IntrinsicData {
struct BuiltinData {
std::string name;
std::string op;
};
inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
out << data.name;
return out;
}
using IntrinsicBoolTest = IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(IntrinsicBoolTest, Call_Bool_Scalar) {
using BuiltinBoolTest = BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(BuiltinBoolTest, Call_Bool_Scalar) {
auto param = GetParam();
auto* var = Global("v", ty.bool_(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
@ -67,7 +67,7 @@ TEST_P(IntrinsicBoolTest, Call_Bool_Scalar) {
"%10 = OpLoad %3 %1\nOpReturn\n");
}
TEST_P(IntrinsicBoolTest, Call_Bool_Vector) {
TEST_P(BuiltinBoolTest, Call_Bool_Vector) {
auto param = GetParam();
auto* var = Global("v", ty.vec3<bool>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
@ -97,13 +97,13 @@ OpReturn
"${op}", param.op);
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
}
INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
IntrinsicBoolTest,
testing::Values(IntrinsicData{"any", "OpAny"},
IntrinsicData{"all", "OpAll"}));
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
BuiltinBoolTest,
testing::Values(BuiltinData{"any", "OpAny"},
BuiltinData{"all", "OpAll"}));
using IntrinsicFloatTest = IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(IntrinsicFloatTest, Call_Float_Scalar) {
using BuiltinFloatTest = BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(BuiltinFloatTest, Call_Float_Scalar) {
auto param = GetParam();
auto* var = Global("v", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
@ -134,7 +134,7 @@ OpReturn
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
}
TEST_P(IntrinsicFloatTest, Call_Float_Vector) {
TEST_P(BuiltinFloatTest, Call_Float_Vector) {
auto param = GetParam();
auto* var = Global("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
@ -166,12 +166,12 @@ OpReturn
"${op}", param.op);
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
}
INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
IntrinsicFloatTest,
testing::Values(IntrinsicData{"isNan", "OpIsNan"},
IntrinsicData{"isInf", "OpIsInf"}));
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
BuiltinFloatTest,
testing::Values(BuiltinData{"isNan", "OpIsNan"},
BuiltinData{"isInf", "OpIsInf"}));
TEST_F(IntrinsicBuilderTest, IsFinite_Scalar) {
TEST_F(BuiltinBuilderTest, IsFinite_Scalar) {
auto* var = Global("v", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call("isFinite", "v");
auto* func = Func("a_func", {}, ty.void_(),
@ -202,7 +202,7 @@ OpReturn
)");
}
TEST_F(IntrinsicBuilderTest, IsFinite_Vector) {
TEST_F(BuiltinBuilderTest, IsFinite_Vector) {
auto* var = Global("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("isFinite", "v");
auto* func = Func("a_func", {}, ty.void_(),
@ -235,7 +235,7 @@ OpReturn
)");
}
TEST_F(IntrinsicBuilderTest, IsNormal_Scalar) {
TEST_F(BuiltinBuilderTest, IsNormal_Scalar) {
auto* var = Global("v", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call("isNormal", "v");
auto* func = Func("a_func", {}, ty.void_(),
@ -275,7 +275,7 @@ OpFunctionEnd
)");
}
TEST_F(IntrinsicBuilderTest, IsNormal_Vector) {
TEST_F(BuiltinBuilderTest, IsNormal_Vector) {
auto* var = Global("v", ty.vec2<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("isNormal", "v");
auto* func = Func("a_func", {}, ty.void_(),
@ -321,8 +321,8 @@ OpFunctionEnd
)");
}
using IntrinsicIntTest = IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(IntrinsicIntTest, Call_SInt_Scalar) {
using BuiltinIntTest = BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(BuiltinIntTest, Call_SInt_Scalar) {
auto param = GetParam();
auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
@ -352,7 +352,7 @@ OpReturn
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
}
TEST_P(IntrinsicIntTest, Call_SInt_Vector) {
TEST_P(BuiltinIntTest, Call_SInt_Vector) {
auto param = GetParam();
auto* var = Global("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
@ -383,7 +383,7 @@ OpReturn
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
}
TEST_P(IntrinsicIntTest, Call_UInt_Scalar) {
TEST_P(BuiltinIntTest, Call_UInt_Scalar) {
auto param = GetParam();
auto* var = Global("v", ty.u32(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
@ -413,7 +413,7 @@ OpReturn
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
}
TEST_P(IntrinsicIntTest, Call_UInt_Vector) {
TEST_P(BuiltinIntTest, Call_UInt_Vector) {
auto param = GetParam();
auto* var = Global("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
@ -444,12 +444,12 @@ OpReturn
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
}
INSTANTIATE_TEST_SUITE_P(
IntrinsicBuilderTest,
IntrinsicIntTest,
testing::Values(IntrinsicData{"countOneBits", "OpBitCount"},
IntrinsicData{"reverseBits", "OpBitReverse"}));
BuiltinBuilderTest,
BuiltinIntTest,
testing::Values(BuiltinData{"countOneBits", "OpBitCount"},
BuiltinData{"reverseBits", "OpBitReverse"}));
TEST_F(IntrinsicBuilderTest, Call_Dot_F32) {
TEST_F(BuiltinBuilderTest, Call_Dot_F32) {
auto* var = Global("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "v", "v");
auto* func = Func("a_func", {}, ty.void_(),
@ -478,7 +478,7 @@ OpReturn
)");
}
TEST_F(IntrinsicBuilderTest, Call_Dot_U32) {
TEST_F(BuiltinBuilderTest, Call_Dot_U32) {
auto* var = Global("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "v", "v");
auto* func = Func("a_func", {}, ty.void_(),
@ -517,7 +517,7 @@ OpReturn
)");
}
TEST_F(IntrinsicBuilderTest, Call_Dot_I32) {
TEST_F(BuiltinBuilderTest, Call_Dot_I32) {
auto* var = Global("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
auto* expr = Call("dot", "v", "v");
auto* func = Func("a_func", {}, ty.void_(),
@ -556,8 +556,8 @@ OpReturn
)");
}
using IntrinsicDeriveTest = IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(IntrinsicDeriveTest, Call_Derivative_Scalar) {
using BuiltinDeriveTest = BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(BuiltinDeriveTest, Call_Derivative_Scalar) {
auto param = GetParam();
auto* var = Global("v", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
@ -585,7 +585,7 @@ OpReturn
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
}
TEST_P(IntrinsicDeriveTest, Call_Derivative_Vector) {
TEST_P(BuiltinDeriveTest, Call_Derivative_Vector) {
auto param = GetParam();
auto* var = Global("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call(param.name, "v");
@ -620,19 +620,19 @@ OpReturn
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
}
INSTANTIATE_TEST_SUITE_P(
IntrinsicBuilderTest,
IntrinsicDeriveTest,
testing::Values(IntrinsicData{"dpdx", "OpDPdx"},
IntrinsicData{"dpdxFine", "OpDPdxFine"},
IntrinsicData{"dpdxCoarse", "OpDPdxCoarse"},
IntrinsicData{"dpdy", "OpDPdy"},
IntrinsicData{"dpdyFine", "OpDPdyFine"},
IntrinsicData{"dpdyCoarse", "OpDPdyCoarse"},
IntrinsicData{"fwidth", "OpFwidth"},
IntrinsicData{"fwidthFine", "OpFwidthFine"},
IntrinsicData{"fwidthCoarse", "OpFwidthCoarse"}));
BuiltinBuilderTest,
BuiltinDeriveTest,
testing::Values(BuiltinData{"dpdx", "OpDPdx"},
BuiltinData{"dpdxFine", "OpDPdxFine"},
BuiltinData{"dpdxCoarse", "OpDPdxCoarse"},
BuiltinData{"dpdy", "OpDPdy"},
BuiltinData{"dpdyFine", "OpDPdyFine"},
BuiltinData{"dpdyCoarse", "OpDPdyCoarse"},
BuiltinData{"fwidth", "OpFwidth"},
BuiltinData{"fwidthFine", "OpFwidthFine"},
BuiltinData{"fwidthCoarse", "OpFwidthCoarse"}));
TEST_F(IntrinsicBuilderTest, Call_Select) {
TEST_F(BuiltinBuilderTest, Call_Select) {
auto* v3 = Global("v3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
auto* bool_v3 =
@ -672,7 +672,7 @@ OpReturn
}
// This tests that we do not push OpTypeSampledImage and float_0 type twice.
TEST_F(IntrinsicBuilderTest, Call_TextureSampleCompare_Twice) {
TEST_F(BuiltinBuilderTest, Call_TextureSampleCompare_Twice) {
auto* s = ty.sampler(ast::SamplerKind::kComparisonSampler);
auto* t = ty.depth_texture(ast::TextureDimension::k2d);
@ -732,7 +732,7 @@ TEST_F(IntrinsicBuilderTest, Call_TextureSampleCompare_Twice) {
)");
}
TEST_F(IntrinsicBuilderTest, Call_GLSLMethod_WithLoad) {
TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad) {
auto* var = Global("ident", ty.f32(), ast::StorageClass::kPrivate);
auto* expr = Call("round", "ident");
auto* func = Func("a_func", {}, ty.void_(),
@ -763,9 +763,9 @@ OpFunctionEnd
)");
}
using Intrinsic_Builtin_SingleParam_Float_Test =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_SingleParam_Float_Test, Call_Scalar) {
using Builtin_Builtin_SingleParam_Float_Test =
BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_SingleParam_Float_Test, Call_Scalar) {
auto param = GetParam();
auto* expr = Call(param.name, 1.0f);
auto* func = Func("a_func", {}, ty.void_(),
@ -792,7 +792,7 @@ OpFunctionEnd
)");
}
TEST_P(Intrinsic_Builtin_SingleParam_Float_Test, Call_Vector) {
TEST_P(Builtin_Builtin_SingleParam_Float_Test, Call_Vector) {
auto param = GetParam();
auto* expr = Call(param.name, vec2<f32>(1.0f, 1.0f));
auto* func = Func("a_func", {}, ty.void_(),
@ -820,35 +820,35 @@ OpReturn
OpFunctionEnd
)");
}
INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
Intrinsic_Builtin_SingleParam_Float_Test,
testing::Values(IntrinsicData{"abs", "FAbs"},
IntrinsicData{"acos", "Acos"},
IntrinsicData{"asin", "Asin"},
IntrinsicData{"atan", "Atan"},
IntrinsicData{"ceil", "Ceil"},
IntrinsicData{"cos", "Cos"},
IntrinsicData{"cosh", "Cosh"},
IntrinsicData{"degrees", "Degrees"},
IntrinsicData{"exp", "Exp"},
IntrinsicData{"exp2", "Exp2"},
IntrinsicData{"floor", "Floor"},
IntrinsicData{"fract", "Fract"},
IntrinsicData{"inverseSqrt",
"InverseSqrt"},
IntrinsicData{"log", "Log"},
IntrinsicData{"log2", "Log2"},
IntrinsicData{"radians", "Radians"},
IntrinsicData{"round", "RoundEven"},
IntrinsicData{"sign", "FSign"},
IntrinsicData{"sin", "Sin"},
IntrinsicData{"sinh", "Sinh"},
IntrinsicData{"sqrt", "Sqrt"},
IntrinsicData{"tan", "Tan"},
IntrinsicData{"tanh", "Tanh"},
IntrinsicData{"trunc", "Trunc"}));
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
Builtin_Builtin_SingleParam_Float_Test,
testing::Values(BuiltinData{"abs", "FAbs"},
BuiltinData{"acos", "Acos"},
BuiltinData{"asin", "Asin"},
BuiltinData{"atan", "Atan"},
BuiltinData{"ceil", "Ceil"},
BuiltinData{"cos", "Cos"},
BuiltinData{"cosh", "Cosh"},
BuiltinData{"degrees", "Degrees"},
BuiltinData{"exp", "Exp"},
BuiltinData{"exp2", "Exp2"},
BuiltinData{"floor", "Floor"},
BuiltinData{"fract", "Fract"},
BuiltinData{"inverseSqrt",
"InverseSqrt"},
BuiltinData{"log", "Log"},
BuiltinData{"log2", "Log2"},
BuiltinData{"radians", "Radians"},
BuiltinData{"round", "RoundEven"},
BuiltinData{"sign", "FSign"},
BuiltinData{"sin", "Sin"},
BuiltinData{"sinh", "Sinh"},
BuiltinData{"sqrt", "Sqrt"},
BuiltinData{"tan", "Tan"},
BuiltinData{"tanh", "Tanh"},
BuiltinData{"trunc", "Trunc"}));
TEST_F(IntrinsicBuilderTest, Call_Length_Scalar) {
TEST_F(BuiltinBuilderTest, Call_Length_Scalar) {
auto* expr = Call("length", 1.0f);
auto* func = Func("a_func", {}, ty.void_(),
{
@ -873,7 +873,7 @@ OpFunctionEnd
)");
}
TEST_F(IntrinsicBuilderTest, Call_Length_Vector) {
TEST_F(BuiltinBuilderTest, Call_Length_Vector) {
auto* expr = Call("length", vec2<f32>(1.0f, 1.0f));
auto* func = Func("a_func", {}, ty.void_(),
{
@ -900,7 +900,7 @@ OpFunctionEnd
)");
}
TEST_F(IntrinsicBuilderTest, Call_Normalize) {
TEST_F(BuiltinBuilderTest, Call_Normalize) {
auto* expr = Call("normalize", vec2<f32>(1.0f, 1.0f));
auto* func = Func("a_func", {}, ty.void_(),
{
@ -927,9 +927,9 @@ OpFunctionEnd
)");
}
using Intrinsic_Builtin_DualParam_Float_Test =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_DualParam_Float_Test, Call_Scalar) {
using Builtin_Builtin_DualParam_Float_Test =
BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_DualParam_Float_Test, Call_Scalar) {
auto param = GetParam();
auto* expr = Call(param.name, 1.0f, 1.0f);
auto* func = Func("a_func", {}, ty.void_(),
@ -956,7 +956,7 @@ OpFunctionEnd
)");
}
TEST_P(Intrinsic_Builtin_DualParam_Float_Test, Call_Vector) {
TEST_P(Builtin_Builtin_DualParam_Float_Test, Call_Vector) {
auto param = GetParam();
auto* expr = Call(param.name, vec2<f32>(1.0f, 1.0f), vec2<f32>(1.0f, 1.0f));
auto* func = Func("a_func", {}, ty.void_(),
@ -984,15 +984,15 @@ OpReturn
OpFunctionEnd
)");
}
INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
Intrinsic_Builtin_DualParam_Float_Test,
testing::Values(IntrinsicData{"atan2", "Atan2"},
IntrinsicData{"max", "NMax"},
IntrinsicData{"min", "NMin"},
IntrinsicData{"pow", "Pow"},
IntrinsicData{"step", "Step"}));
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
Builtin_Builtin_DualParam_Float_Test,
testing::Values(BuiltinData{"atan2", "Atan2"},
BuiltinData{"max", "NMax"},
BuiltinData{"min", "NMin"},
BuiltinData{"pow", "Pow"},
BuiltinData{"step", "Step"}));
TEST_F(IntrinsicBuilderTest, Call_Reflect_Vector) {
TEST_F(BuiltinBuilderTest, Call_Reflect_Vector) {
auto* expr = Call("reflect", vec2<f32>(1.0f, 1.0f), vec2<f32>(1.0f, 1.0f));
auto* func = Func("a_func", {}, ty.void_(),
{
@ -1019,7 +1019,7 @@ OpFunctionEnd
)");
}
TEST_F(IntrinsicBuilderTest, Call_Distance_Scalar) {
TEST_F(BuiltinBuilderTest, Call_Distance_Scalar) {
auto* expr = Call("distance", 1.0f, 1.0f);
auto* func = Func("a_func", {}, ty.void_(),
{
@ -1044,7 +1044,7 @@ OpFunctionEnd
)");
}
TEST_F(IntrinsicBuilderTest, Call_Distance_Vector) {
TEST_F(BuiltinBuilderTest, Call_Distance_Vector) {
auto* expr = Call("distance", vec2<f32>(1.0f, 1.0f), vec2<f32>(1.0f, 1.0f));
auto* func = Func("a_func", {}, ty.void_(),
{
@ -1071,7 +1071,7 @@ OpFunctionEnd
)");
}
TEST_F(IntrinsicBuilderTest, Call_Cross) {
TEST_F(BuiltinBuilderTest, Call_Cross) {
auto* expr =
Call("cross", vec3<f32>(1.0f, 1.0f, 1.0f), vec3<f32>(1.0f, 1.0f, 1.0f));
auto* func = Func("a_func", {}, ty.void_(),
@ -1099,9 +1099,9 @@ OpFunctionEnd
)");
}
using Intrinsic_Builtin_ThreeParam_Float_Test =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_ThreeParam_Float_Test, Call_Scalar) {
using Builtin_Builtin_ThreeParam_Float_Test =
BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_ThreeParam_Float_Test, Call_Scalar) {
auto param = GetParam();
auto* expr = Call(param.name, 1.0f, 1.0f, 1.0f);
auto* func = Func("a_func", {}, ty.void_(),
@ -1128,7 +1128,7 @@ OpFunctionEnd
)");
}
TEST_P(Intrinsic_Builtin_ThreeParam_Float_Test, Call_Vector) {
TEST_P(Builtin_Builtin_ThreeParam_Float_Test, Call_Vector) {
auto param = GetParam();
auto* expr = Call(param.name, vec2<f32>(1.0f, 1.0f), vec2<f32>(1.0f, 1.0f),
vec2<f32>(1.0f, 1.0f));
@ -1157,16 +1157,16 @@ OpReturn
OpFunctionEnd
)");
}
INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
Intrinsic_Builtin_ThreeParam_Float_Test,
testing::Values(IntrinsicData{"clamp", "NClamp"},
IntrinsicData{"fma", "Fma"},
IntrinsicData{"mix", "FMix"},
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
Builtin_Builtin_ThreeParam_Float_Test,
testing::Values(BuiltinData{"clamp", "NClamp"},
BuiltinData{"fma", "Fma"},
BuiltinData{"mix", "FMix"},
IntrinsicData{"smoothStep",
"SmoothStep"}));
BuiltinData{"smoothStep",
"SmoothStep"}));
TEST_F(IntrinsicBuilderTest, Call_FaceForward_Vector) {
TEST_F(BuiltinBuilderTest, Call_FaceForward_Vector) {
auto* expr = Call("faceForward", vec2<f32>(1.0f, 1.0f), vec2<f32>(1.0f, 1.0f),
vec2<f32>(1.0f, 1.0f));
auto* func = Func("a_func", {}, ty.void_(),
@ -1194,9 +1194,9 @@ OpFunctionEnd
)");
}
using Intrinsic_Builtin_SingleParam_Sint_Test =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_SingleParam_Sint_Test, Call_Scalar) {
using Builtin_Builtin_SingleParam_Sint_Test =
BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_SingleParam_Sint_Test, Call_Scalar) {
auto param = GetParam();
auto* expr = Call(param.name, 1);
auto* func = Func("a_func", {}, ty.void_(),
@ -1223,7 +1223,7 @@ OpFunctionEnd
)");
}
TEST_P(Intrinsic_Builtin_SingleParam_Sint_Test, Call_Vector) {
TEST_P(Builtin_Builtin_SingleParam_Sint_Test, Call_Vector) {
auto param = GetParam();
auto* expr = Call(param.name, vec2<i32>(1, 1));
auto* func = Func("a_func", {}, ty.void_(),
@ -1251,13 +1251,13 @@ OpReturn
OpFunctionEnd
)");
}
INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
Intrinsic_Builtin_SingleParam_Sint_Test,
testing::Values(IntrinsicData{"abs", "SAbs"}));
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
Builtin_Builtin_SingleParam_Sint_Test,
testing::Values(BuiltinData{"abs", "SAbs"}));
// Calling abs() on an unsigned integer scalar / vector is a no-op.
using Intrinsic_Builtin_Abs_Uint_Test = IntrinsicBuilderTest;
TEST_F(Intrinsic_Builtin_Abs_Uint_Test, Call_Scalar) {
using Builtin_Builtin_Abs_Uint_Test = BuiltinBuilderTest;
TEST_F(Builtin_Builtin_Abs_Uint_Test, Call_Scalar) {
auto* expr = Call("abs", 1u);
auto* func = Func("a_func", {}, ty.void_(),
{
@ -1280,7 +1280,7 @@ OpFunctionEnd
)");
}
TEST_F(Intrinsic_Builtin_Abs_Uint_Test, Call_Vector) {
TEST_F(Builtin_Builtin_Abs_Uint_Test, Call_Vector) {
auto* expr = Call("abs", vec2<u32>(1u, 1u));
auto* func = Func("a_func", {}, ty.void_(),
{
@ -1305,9 +1305,9 @@ OpFunctionEnd
)");
}
using Intrinsic_Builtin_DualParam_SInt_Test =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_DualParam_SInt_Test, Call_Scalar) {
using Builtin_Builtin_DualParam_SInt_Test =
BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_DualParam_SInt_Test, Call_Scalar) {
auto param = GetParam();
auto* expr = Call(param.name, 1, 1);
auto* func = Func("a_func", {}, ty.void_(),
@ -1334,7 +1334,7 @@ OpFunctionEnd
)");
}
TEST_P(Intrinsic_Builtin_DualParam_SInt_Test, Call_Vector) {
TEST_P(Builtin_Builtin_DualParam_SInt_Test, Call_Vector) {
auto param = GetParam();
auto* expr = Call(param.name, vec2<i32>(1, 1), vec2<i32>(1, 1));
auto* func = Func("a_func", {}, ty.void_(),
@ -1362,14 +1362,14 @@ OpReturn
OpFunctionEnd
)");
}
INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
Intrinsic_Builtin_DualParam_SInt_Test,
testing::Values(IntrinsicData{"max", "SMax"},
IntrinsicData{"min", "SMin"}));
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
Builtin_Builtin_DualParam_SInt_Test,
testing::Values(BuiltinData{"max", "SMax"},
BuiltinData{"min", "SMin"}));
using Intrinsic_Builtin_DualParam_UInt_Test =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_DualParam_UInt_Test, Call_Scalar) {
using Builtin_Builtin_DualParam_UInt_Test =
BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_DualParam_UInt_Test, Call_Scalar) {
auto param = GetParam();
auto* expr = Call(param.name, 1u, 1u);
auto* func = Func("a_func", {}, ty.void_(),
@ -1396,7 +1396,7 @@ OpFunctionEnd
)");
}
TEST_P(Intrinsic_Builtin_DualParam_UInt_Test, Call_Vector) {
TEST_P(Builtin_Builtin_DualParam_UInt_Test, Call_Vector) {
auto param = GetParam();
auto* expr = Call(param.name, vec2<u32>(1u, 1u), vec2<u32>(1u, 1u));
auto* func = Func("a_func", {}, ty.void_(),
@ -1424,14 +1424,14 @@ OpReturn
OpFunctionEnd
)");
}
INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
Intrinsic_Builtin_DualParam_UInt_Test,
testing::Values(IntrinsicData{"max", "UMax"},
IntrinsicData{"min", "UMin"}));
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
Builtin_Builtin_DualParam_UInt_Test,
testing::Values(BuiltinData{"max", "UMax"},
BuiltinData{"min", "UMin"}));
using Intrinsic_Builtin_ThreeParam_Sint_Test =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_ThreeParam_Sint_Test, Call_Scalar) {
using Builtin_Builtin_ThreeParam_Sint_Test =
BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_ThreeParam_Sint_Test, Call_Scalar) {
auto param = GetParam();
auto* expr = Call(param.name, 1, 1, 1);
auto* func = Func("a_func", {}, ty.void_(),
@ -1458,7 +1458,7 @@ OpFunctionEnd
)");
}
TEST_P(Intrinsic_Builtin_ThreeParam_Sint_Test, Call_Vector) {
TEST_P(Builtin_Builtin_ThreeParam_Sint_Test, Call_Vector) {
auto param = GetParam();
auto* expr =
Call(param.name, vec2<i32>(1, 1), vec2<i32>(1, 1), vec2<i32>(1, 1));
@ -1487,13 +1487,13 @@ OpReturn
OpFunctionEnd
)");
}
INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
Intrinsic_Builtin_ThreeParam_Sint_Test,
testing::Values(IntrinsicData{"clamp", "SClamp"}));
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
Builtin_Builtin_ThreeParam_Sint_Test,
testing::Values(BuiltinData{"clamp", "SClamp"}));
using Intrinsic_Builtin_ThreeParam_Uint_Test =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_ThreeParam_Uint_Test, Call_Scalar) {
using Builtin_Builtin_ThreeParam_Uint_Test =
BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_ThreeParam_Uint_Test, Call_Scalar) {
auto param = GetParam();
auto* expr = Call(param.name, 1u, 1u, 1u);
auto* func = Func("a_func", {}, ty.void_(),
@ -1520,7 +1520,7 @@ OpFunctionEnd
)");
}
TEST_P(Intrinsic_Builtin_ThreeParam_Uint_Test, Call_Vector) {
TEST_P(Builtin_Builtin_ThreeParam_Uint_Test, Call_Vector) {
auto param = GetParam();
auto* expr =
Call(param.name, vec2<u32>(1u, 1u), vec2<u32>(1u, 1u), vec2<u32>(1u, 1u));
@ -1549,11 +1549,11 @@ OpReturn
OpFunctionEnd
)");
}
INSTANTIATE_TEST_SUITE_P(IntrinsicBuilderTest,
Intrinsic_Builtin_ThreeParam_Uint_Test,
testing::Values(IntrinsicData{"clamp", "UClamp"}));
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
Builtin_Builtin_ThreeParam_Uint_Test,
testing::Values(BuiltinData{"clamp", "UClamp"}));
TEST_F(IntrinsicBuilderTest, Call_Modf) {
TEST_F(BuiltinBuilderTest, Call_Modf) {
auto* expr = Call("modf", vec2<f32>(1.0f, 2.0f));
Func("a_func", {}, ty.void_(), {CallStmt(expr)},
{Stage(ast::PipelineStage::kFragment)});
@ -1592,7 +1592,7 @@ OpFunctionEnd
Validate(b);
}
TEST_F(IntrinsicBuilderTest, Call_Frexp) {
TEST_F(BuiltinBuilderTest, Call_Frexp) {
auto* expr = Call("frexp", vec2<f32>(1.0f, 2.0f));
Func("a_func", {}, ty.void_(), {CallStmt(expr)},
{Stage(ast::PipelineStage::kFragment)});
@ -1633,7 +1633,7 @@ OpFunctionEnd
Validate(b);
}
TEST_F(IntrinsicBuilderTest, Call_Determinant) {
TEST_F(BuiltinBuilderTest, Call_Determinant) {
auto* var = Global("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("determinant", "var");
auto* func = Func("a_func", {}, ty.void_(),
@ -1666,7 +1666,7 @@ OpFunctionEnd
)");
}
TEST_F(IntrinsicBuilderTest, Call_Transpose) {
TEST_F(BuiltinBuilderTest, Call_Transpose) {
auto* var = Global("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
auto* expr = Call("transpose", "var");
auto* func = Func("a_func", {}, ty.void_(),
@ -1700,7 +1700,7 @@ OpFunctionEnd
)");
}
TEST_F(IntrinsicBuilderTest, Call_ArrayLength) {
TEST_F(BuiltinBuilderTest, Call_ArrayLength) {
auto* s = Structure("my_struct", {Member("a", ty.array<f32>(4))},
{create<ast::StructBlockAttribute>()});
Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
@ -1745,7 +1745,7 @@ OpReturn
Validate(b);
}
TEST_F(IntrinsicBuilderTest, Call_ArrayLength_OtherMembersInStruct) {
TEST_F(BuiltinBuilderTest, Call_ArrayLength_OtherMembersInStruct) {
auto* s = Structure("my_struct",
{
Member("z", ty.f32()),
@ -1794,7 +1794,7 @@ OpReturn
Validate(b);
}
TEST_F(IntrinsicBuilderTest, Call_ArrayLength_ViaLets) {
TEST_F(BuiltinBuilderTest, Call_ArrayLength_ViaLets) {
auto* s = Structure("my_struct", {Member("a", ty.array<f32>(4))},
{create<ast::StructBlockAttribute>()});
Global("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
@ -1844,7 +1844,7 @@ OpReturn
Validate(b);
}
TEST_F(IntrinsicBuilderTest, Call_ArrayLength_ViaLets_WithPtrNoise) {
TEST_F(BuiltinBuilderTest, Call_ArrayLength_ViaLets_WithPtrNoise) {
// [[block]] struct my_struct {
// a : @stride(4) array<f32>;
// };
@ -1907,7 +1907,7 @@ OpReturn
Validate(b);
}
TEST_F(IntrinsicBuilderTest, Call_AtomicLoad) {
TEST_F(BuiltinBuilderTest, Call_AtomicLoad) {
// [[block]] struct S {
// u : atomic<u32>;
// i : atomic<i32>;
@ -1973,7 +1973,7 @@ OpReturn
Validate(b);
}
TEST_F(IntrinsicBuilderTest, Call_AtomicStore) {
TEST_F(BuiltinBuilderTest, Call_AtomicStore) {
// [[block]] struct S {
// u : atomic<u32>;
// i : atomic<i32>;
@ -2052,9 +2052,8 @@ OpReturn
Validate(b);
}
using Intrinsic_Builtin_AtomicRMW_i32 =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_AtomicRMW_i32, Test) {
using Builtin_Builtin_AtomicRMW_i32 = BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_AtomicRMW_i32, Test) {
// [[block]] struct S {
// v : atomic<i32>;
// }
@ -2121,18 +2120,17 @@ TEST_P(Intrinsic_Builtin_AtomicRMW_i32, Test) {
Validate(b);
}
INSTANTIATE_TEST_SUITE_P(
IntrinsicBuilderTest,
Intrinsic_Builtin_AtomicRMW_i32,
testing::Values(IntrinsicData{"atomicAdd", "OpAtomicIAdd"},
IntrinsicData{"atomicMax", "OpAtomicSMax"},
IntrinsicData{"atomicMin", "OpAtomicSMin"},
IntrinsicData{"atomicAnd", "OpAtomicAnd"},
IntrinsicData{"atomicOr", "OpAtomicOr"},
IntrinsicData{"atomicXor", "OpAtomicXor"}));
BuiltinBuilderTest,
Builtin_Builtin_AtomicRMW_i32,
testing::Values(BuiltinData{"atomicAdd", "OpAtomicIAdd"},
BuiltinData{"atomicMax", "OpAtomicSMax"},
BuiltinData{"atomicMin", "OpAtomicSMin"},
BuiltinData{"atomicAnd", "OpAtomicAnd"},
BuiltinData{"atomicOr", "OpAtomicOr"},
BuiltinData{"atomicXor", "OpAtomicXor"}));
using Intrinsic_Builtin_AtomicRMW_u32 =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_AtomicRMW_u32, Test) {
using Builtin_Builtin_AtomicRMW_u32 = BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_AtomicRMW_u32, Test) {
// [[block]] struct S {
// v : atomic<u32>;
// }
@ -2198,16 +2196,16 @@ TEST_P(Intrinsic_Builtin_AtomicRMW_u32, Test) {
Validate(b);
}
INSTANTIATE_TEST_SUITE_P(
IntrinsicBuilderTest,
Intrinsic_Builtin_AtomicRMW_u32,
testing::Values(IntrinsicData{"atomicAdd", "OpAtomicIAdd"},
IntrinsicData{"atomicMax", "OpAtomicUMax"},
IntrinsicData{"atomicMin", "OpAtomicUMin"},
IntrinsicData{"atomicAnd", "OpAtomicAnd"},
IntrinsicData{"atomicOr", "OpAtomicOr"},
IntrinsicData{"atomicXor", "OpAtomicXor"}));
BuiltinBuilderTest,
Builtin_Builtin_AtomicRMW_u32,
testing::Values(BuiltinData{"atomicAdd", "OpAtomicIAdd"},
BuiltinData{"atomicMax", "OpAtomicUMax"},
BuiltinData{"atomicMin", "OpAtomicUMin"},
BuiltinData{"atomicAnd", "OpAtomicAnd"},
BuiltinData{"atomicOr", "OpAtomicOr"},
BuiltinData{"atomicXor", "OpAtomicXor"}));
TEST_F(IntrinsicBuilderTest, Call_AtomicExchange) {
TEST_F(BuiltinBuilderTest, Call_AtomicExchange) {
// [[block]] struct S {
// u : atomic<u32>;
// i : atomic<i32>;
@ -2289,7 +2287,7 @@ OpReturn
Validate(b);
}
TEST_F(IntrinsicBuilderTest, Call_AtomicCompareExchangeWeak) {
TEST_F(BuiltinBuilderTest, Call_AtomicCompareExchangeWeak) {
// [[block]] struct S {
// u : atomic<u32>;
// i : atomic<i32>;
@ -2372,9 +2370,9 @@ OpReturn
Validate(b);
}
using Intrinsic_Builtin_DataPacking_Test =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_DataPacking_Test, Binary) {
using Builtin_Builtin_DataPacking_Test =
BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_DataPacking_Test, Binary) {
auto param = GetParam();
bool pack4 = param.name == "pack4x8snorm" || param.name == "pack4x8unorm";
@ -2424,17 +2422,17 @@ OpFunctionEnd
}
INSTANTIATE_TEST_SUITE_P(
IntrinsicBuilderTest,
Intrinsic_Builtin_DataPacking_Test,
testing::Values(IntrinsicData{"pack4x8snorm", "PackSnorm4x8"},
IntrinsicData{"pack4x8unorm", "PackUnorm4x8"},
IntrinsicData{"pack2x16snorm", "PackSnorm2x16"},
IntrinsicData{"pack2x16unorm", "PackUnorm2x16"},
IntrinsicData{"pack2x16float", "PackHalf2x16"}));
BuiltinBuilderTest,
Builtin_Builtin_DataPacking_Test,
testing::Values(BuiltinData{"pack4x8snorm", "PackSnorm4x8"},
BuiltinData{"pack4x8unorm", "PackUnorm4x8"},
BuiltinData{"pack2x16snorm", "PackSnorm2x16"},
BuiltinData{"pack2x16unorm", "PackUnorm2x16"},
BuiltinData{"pack2x16float", "PackHalf2x16"}));
using Intrinsic_Builtin_DataUnpacking_Test =
IntrinsicBuilderTestWithParam<IntrinsicData>;
TEST_P(Intrinsic_Builtin_DataUnpacking_Test, Binary) {
using Builtin_Builtin_DataUnpacking_Test =
BuiltinBuilderTestWithParam<BuiltinData>;
TEST_P(Builtin_Builtin_DataUnpacking_Test, Binary) {
auto param = GetParam();
bool pack4 = param.name == "unpack4x8snorm" || param.name == "unpack4x8unorm";
@ -2480,15 +2478,15 @@ OpFunctionEnd
}
INSTANTIATE_TEST_SUITE_P(
IntrinsicBuilderTest,
Intrinsic_Builtin_DataUnpacking_Test,
testing::Values(IntrinsicData{"unpack4x8snorm", "UnpackSnorm4x8"},
IntrinsicData{"unpack4x8unorm", "UnpackUnorm4x8"},
IntrinsicData{"unpack2x16snorm", "UnpackSnorm2x16"},
IntrinsicData{"unpack2x16unorm", "UnpackUnorm2x16"},
IntrinsicData{"unpack2x16float", "UnpackHalf2x16"}));
BuiltinBuilderTest,
Builtin_Builtin_DataUnpacking_Test,
testing::Values(BuiltinData{"unpack4x8snorm", "UnpackSnorm4x8"},
BuiltinData{"unpack4x8unorm", "UnpackUnorm4x8"},
BuiltinData{"unpack2x16snorm", "UnpackSnorm2x16"},
BuiltinData{"unpack2x16unorm", "UnpackUnorm2x16"},
BuiltinData{"unpack2x16float", "UnpackHalf2x16"}));
TEST_F(IntrinsicBuilderTest, Call_WorkgroupBarrier) {
TEST_F(BuiltinBuilderTest, Call_WorkgroupBarrier) {
Func("f", {}, ty.void_(),
ast::StatementList{
CallStmt(Call("workgroupBarrier")),
@ -2522,7 +2520,7 @@ OpReturn
Validate(b);
}
TEST_F(IntrinsicBuilderTest, Call_StorageBarrier) {
TEST_F(BuiltinBuilderTest, Call_StorageBarrier) {
Func("f", {}, ty.void_(),
ast::StatementList{
CallStmt(Call("storageBarrier")),

View File

@ -13,8 +13,8 @@
// limitations under the License.
#include "gmock/gmock.h"
#include "src/ast/builtin_texture_helper_test.h"
#include "src/ast/call_statement.h"
#include "src/ast/intrinsic_texture_helper_test.h"
#include "src/ast/stage_attribute.h"
#include "src/writer/spirv/spv_dump.h"
#include "src/writer/spirv/test_helper.h"
@ -31,8 +31,8 @@ struct expected_texture_overload_spirv {
};
expected_texture_overload_spirv expected_texture_overload(
ast::intrinsic::test::ValidTextureOverload overload) {
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
ast::builtin::test::ValidTextureOverload overload) {
using ValidTextureOverload = ast::builtin::test::ValidTextureOverload;
switch (overload) {
case ValidTextureOverload::kDimensions1d:
return {
@ -3672,15 +3672,15 @@ OpImageWrite %10 %16 %22
"<unmatched texture overload>"};
} // NOLINT - Ignore the length of this function
using IntrinsicTextureTest =
TestParamHelper<ast::intrinsic::test::TextureOverloadCase>;
using BuiltinTextureTest =
TestParamHelper<ast::builtin::test::TextureOverloadCase>;
INSTANTIATE_TEST_SUITE_P(
IntrinsicTextureTest,
IntrinsicTextureTest,
testing::ValuesIn(ast::intrinsic::test::TextureOverloadCase::ValidCases()));
BuiltinTextureTest,
BuiltinTextureTest,
testing::ValuesIn(ast::builtin::test::TextureOverloadCase::ValidCases()));
TEST_P(IntrinsicTextureTest, Call) {
TEST_P(BuiltinTextureTest, Call) {
auto param = GetParam();
auto* texture = param.BuildTextureVariable(this);
@ -3706,7 +3706,7 @@ TEST_P(IntrinsicTextureTest, Call) {
}
// Check the SPIRV generated passes validation
TEST_P(IntrinsicTextureTest, ValidateSPIRV) {
TEST_P(BuiltinTextureTest, ValidateSPIRV) {
auto param = GetParam();
param.BuildTextureVariable(this);
@ -3724,11 +3724,11 @@ TEST_P(IntrinsicTextureTest, ValidateSPIRV) {
Validate(b);
}
TEST_P(IntrinsicTextureTest, OutsideFunction_IsError) {
TEST_P(BuiltinTextureTest, OutsideFunction_IsError) {
auto param = GetParam();
// The point of this test is to try to generate the texture
// intrinsic call outside a function.
// builtin call outside a function.
auto* texture = param.BuildTextureVariable(this);
auto* sampler = param.BuildSamplerVariable(this);

View File

@ -153,6 +153,8 @@ tint_unittests_source_set("tint_unittests_ast_src") {
"../src/ast/bool_test.cc",
"../src/ast/break_statement_test.cc",
"../src/ast/builtin_attribute_test.cc",
"../src/ast/builtin_texture_helper_test.cc",
"../src/ast/builtin_texture_helper_test.h",
"../src/ast/call_expression_test.cc",
"../src/ast/call_statement_test.cc",
"../src/ast/case_statement_test.cc",
@ -174,8 +176,6 @@ tint_unittests_source_set("tint_unittests_ast_src") {
"../src/ast/index_accessor_expression_test.cc",
"../src/ast/int_literal_expression_test.cc",
"../src/ast/interpolate_attribute_test.cc",
"../src/ast/intrinsic_texture_helper_test.cc",
"../src/ast/intrinsic_texture_helper_test.h",
"../src/ast/invariant_attribute_test.cc",
"../src/ast/location_attribute_test.cc",
"../src/ast/loop_statement_test.cc",
@ -239,6 +239,8 @@ tint_unittests_source_set("tint_unittests_resolver_src") {
"../src/resolver/atomics_validation_test.cc",
"../src/resolver/bitcast_validation_test.cc",
"../src/resolver/builtins_validation_test.cc",
"../src/resolver/builtin_test.cc",
"../src/resolver/builtin_validation_test.cc",
"../src/resolver/call_test.cc",
"../src/resolver/call_validation_test.cc",
"../src/resolver/compound_statement_test.cc",
@ -248,8 +250,6 @@ tint_unittests_source_set("tint_unittests_resolver_src") {
"../src/resolver/entry_point_validation_test.cc",
"../src/resolver/function_validation_test.cc",
"../src/resolver/host_shareable_validation_test.cc",
"../src/resolver/intrinsic_test.cc",
"../src/resolver/intrinsic_validation_test.cc",
"../src/resolver/is_host_shareable_test.cc",
"../src/resolver/is_storeable_test.cc",
"../src/resolver/pipeline_overridable_constant_test.cc",
@ -278,12 +278,12 @@ tint_unittests_source_set("tint_unittests_sem_src") {
sources = [
"../src/sem/atomic_type_test.cc",
"../src/sem/bool_type_test.cc",
"../src/sem/builtin_test.cc",
"../src/sem/depth_multisampled_texture_type_test.cc",
"../src/sem/depth_texture_type_test.cc",
"../src/sem/external_texture_type_test.cc",
"../src/sem/f32_type_test.cc",
"../src/sem/i32_type_test.cc",
"../src/sem/intrinsic_test.cc",
"../src/sem/matrix_type_test.cc",
"../src/sem/multisampled_texture_type_test.cc",
"../src/sem/pointer_type_test.cc",
@ -413,6 +413,8 @@ tint_unittests_source_set("tint_unittests_spv_writer_src") {
"../src/writer/spirv/builder_binary_expression_test.cc",
"../src/writer/spirv/builder_bitcast_expression_test.cc",
"../src/writer/spirv/builder_block_test.cc",
"../src/writer/spirv/builder_builtin_test.cc",
"../src/writer/spirv/builder_builtin_texture_test.cc",
"../src/writer/spirv/builder_call_test.cc",
"../src/writer/spirv/builder_constructor_expression_test.cc",
"../src/writer/spirv/builder_discard_test.cc",
@ -424,8 +426,6 @@ tint_unittests_source_set("tint_unittests_spv_writer_src") {
"../src/writer/spirv/builder_global_variable_test.cc",
"../src/writer/spirv/builder_ident_expression_test.cc",
"../src/writer/spirv/builder_if_test.cc",
"../src/writer/spirv/builder_intrinsic_test.cc",
"../src/writer/spirv/builder_intrinsic_texture_test.cc",
"../src/writer/spirv/builder_literal_test.cc",
"../src/writer/spirv/builder_loop_test.cc",
"../src/writer/spirv/builder_return_test.cc",
@ -576,6 +576,8 @@ tint_unittests_source_set("tint_unittests_msl_writer_src") {
"../src/writer/msl/generator_impl_bitcast_test.cc",
"../src/writer/msl/generator_impl_block_test.cc",
"../src/writer/msl/generator_impl_break_test.cc",
"../src/writer/msl/generator_impl_builtin_test.cc",
"../src/writer/msl/generator_impl_builtin_texture_test.cc",
"../src/writer/msl/generator_impl_call_test.cc",
"../src/writer/msl/generator_impl_case_test.cc",
"../src/writer/msl/generator_impl_cast_test.cc",
@ -586,8 +588,6 @@ tint_unittests_source_set("tint_unittests_msl_writer_src") {
"../src/writer/msl/generator_impl_identifier_test.cc",
"../src/writer/msl/generator_impl_if_test.cc",
"../src/writer/msl/generator_impl_import_test.cc",
"../src/writer/msl/generator_impl_intrinsic_test.cc",
"../src/writer/msl/generator_impl_intrinsic_texture_test.cc",
"../src/writer/msl/generator_impl_loop_test.cc",
"../src/writer/msl/generator_impl_member_accessor_test.cc",
"../src/writer/msl/generator_impl_module_constant_test.cc",
@ -615,6 +615,8 @@ tint_unittests_source_set("tint_unittests_hlsl_writer_src") {
"../src/writer/hlsl/generator_impl_bitcast_test.cc",
"../src/writer/hlsl/generator_impl_block_test.cc",
"../src/writer/hlsl/generator_impl_break_test.cc",
"../src/writer/hlsl/generator_impl_builtin_test.cc",
"../src/writer/hlsl/generator_impl_builtin_texture_test.cc",
"../src/writer/hlsl/generator_impl_call_test.cc",
"../src/writer/hlsl/generator_impl_case_test.cc",
"../src/writer/hlsl/generator_impl_cast_test.cc",
@ -625,8 +627,6 @@ tint_unittests_source_set("tint_unittests_hlsl_writer_src") {
"../src/writer/hlsl/generator_impl_identifier_test.cc",
"../src/writer/hlsl/generator_impl_if_test.cc",
"../src/writer/hlsl/generator_impl_import_test.cc",
"../src/writer/hlsl/generator_impl_intrinsic_test.cc",
"../src/writer/hlsl/generator_impl_intrinsic_texture_test.cc",
"../src/writer/hlsl/generator_impl_loop_test.cc",
"../src/writer/hlsl/generator_impl_member_accessor_test.cc",
"../src/writer/hlsl/generator_impl_module_constant_test.cc",
@ -656,6 +656,8 @@ tint_unittests_source_set("tint_unittests_glsl_writer_src") {
"../src/writer/glsl/generator_impl_bitcast_test.cc",
"../src/writer/glsl/generator_impl_block_test.cc",
"../src/writer/glsl/generator_impl_break_test.cc",
"../src/writer/glsl/generator_impl_builtin_test.cc",
"../src/writer/glsl/generator_impl_builtin_texture_test.cc",
"../src/writer/glsl/generator_impl_call_test.cc",
"../src/writer/glsl/generator_impl_case_test.cc",
"../src/writer/glsl/generator_impl_cast_test.cc",
@ -666,8 +668,6 @@ tint_unittests_source_set("tint_unittests_glsl_writer_src") {
"../src/writer/glsl/generator_impl_identifier_test.cc",
"../src/writer/glsl/generator_impl_if_test.cc",
"../src/writer/glsl/generator_impl_import_test.cc",
"../src/writer/glsl/generator_impl_intrinsic_test.cc",
"../src/writer/glsl/generator_impl_intrinsic_texture_test.cc",
"../src/writer/glsl/generator_impl_loop_test.cc",
"../src/writer/glsl/generator_impl_member_accessor_test.cc",
"../src/writer/glsl/generator_impl_module_constant_test.cc",
@ -692,11 +692,11 @@ tint_unittests_source_set("tint_unittests_glsl_writer_src") {
tint_unittests_source_set("tint_unittests_core_src") {
sources = [
"../src/block_allocator_test.cc",
"../src/builtin_table_test.cc",
"../src/castable_test.cc",
"../src/clone_context_test.cc",
"../src/debug_test.cc",
"../src/demangler_test.cc",
"../src/intrinsic_table_test.cc",
"../src/program_builder_test.cc",
"../src/program_test.cc",
"../src/scope_stack_test.cc",

View File

@ -1,20 +1,20 @@
bug/chromium/1273230.wgsl:4:7 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:4:7 warning: use of deprecated builtin
_ = isNormal(4.);
^^^^^^^^
bug/chromium/1273230.wgsl:7:3 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:7:3 warning: use of deprecated builtin
isNormal(vec4<f32>());
^^^^^^^^
bug/chromium/1273230.wgsl:10:6 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:10:6 warning: use of deprecated builtin
isNormal(0.);
^^^^^^^^
bug/chromium/1273230.wgsl:11:9 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:11:9 warning: use of deprecated builtin
_ = isNormal(4.);
^^^^^^^^
bug/chromium/1273230.wgsl:12:9 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:12:9 warning: use of deprecated builtin
_ = isNormal(2.);
^^^^^^^^

View File

@ -1,20 +1,20 @@
bug/chromium/1273230.wgsl:4:7 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:4:7 warning: use of deprecated builtin
_ = isNormal(4.);
^^^^^^^^
bug/chromium/1273230.wgsl:7:3 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:7:3 warning: use of deprecated builtin
isNormal(vec4<f32>());
^^^^^^^^
bug/chromium/1273230.wgsl:10:6 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:10:6 warning: use of deprecated builtin
isNormal(0.);
^^^^^^^^
bug/chromium/1273230.wgsl:11:9 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:11:9 warning: use of deprecated builtin
_ = isNormal(4.);
^^^^^^^^
bug/chromium/1273230.wgsl:12:9 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:12:9 warning: use of deprecated builtin
_ = isNormal(2.);
^^^^^^^^

View File

@ -1,20 +1,20 @@
bug/chromium/1273230.wgsl:4:7 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:4:7 warning: use of deprecated builtin
_ = isNormal(4.);
^^^^^^^^
bug/chromium/1273230.wgsl:7:3 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:7:3 warning: use of deprecated builtin
isNormal(vec4<f32>());
^^^^^^^^
bug/chromium/1273230.wgsl:10:6 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:10:6 warning: use of deprecated builtin
isNormal(0.);
^^^^^^^^
bug/chromium/1273230.wgsl:11:9 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:11:9 warning: use of deprecated builtin
_ = isNormal(4.);
^^^^^^^^
bug/chromium/1273230.wgsl:12:9 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:12:9 warning: use of deprecated builtin
_ = isNormal(2.);
^^^^^^^^

View File

@ -1,20 +1,20 @@
bug/chromium/1273230.wgsl:4:7 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:4:7 warning: use of deprecated builtin
_ = isNormal(4.);
^^^^^^^^
bug/chromium/1273230.wgsl:7:3 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:7:3 warning: use of deprecated builtin
isNormal(vec4<f32>());
^^^^^^^^
bug/chromium/1273230.wgsl:10:6 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:10:6 warning: use of deprecated builtin
isNormal(0.);
^^^^^^^^
bug/chromium/1273230.wgsl:11:9 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:11:9 warning: use of deprecated builtin
_ = isNormal(4.);
^^^^^^^^
bug/chromium/1273230.wgsl:12:9 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:12:9 warning: use of deprecated builtin
_ = isNormal(2.);
^^^^^^^^

View File

@ -1,20 +1,20 @@
bug/chromium/1273230.wgsl:4:7 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:4:7 warning: use of deprecated builtin
_ = isNormal(4.);
^^^^^^^^
bug/chromium/1273230.wgsl:7:3 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:7:3 warning: use of deprecated builtin
isNormal(vec4<f32>());
^^^^^^^^
bug/chromium/1273230.wgsl:10:6 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:10:6 warning: use of deprecated builtin
isNormal(0.);
^^^^^^^^
bug/chromium/1273230.wgsl:11:9 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:11:9 warning: use of deprecated builtin
_ = isNormal(4.);
^^^^^^^^
bug/chromium/1273230.wgsl:12:9 warning: use of deprecated intrinsic
bug/chromium/1273230.wgsl:12:9 warning: use of deprecated builtin
_ = isNormal(2.);
^^^^^^^^

Some files were not shown because too many files have changed in this diff Show More