tint/ast: Clean up StorageClass enum
Remove unused enum entries. Add a ParseStorageClass() function. Have the WGSL parser use this. First step to standardizing the way we parse enum-backed token sets. Change-Id: I31c02816493beeabda740ff43946edce097f5fd1 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97148 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
ce8876074f
commit
48085845bd
|
@ -16,34 +16,52 @@
|
|||
|
||||
namespace tint::ast {
|
||||
|
||||
const char* ToString(StorageClass sc) {
|
||||
switch (sc) {
|
||||
case StorageClass::kInvalid:
|
||||
return "invalid";
|
||||
case StorageClass::kNone:
|
||||
return "none";
|
||||
case StorageClass::kInput:
|
||||
return "in";
|
||||
case StorageClass::kOutput:
|
||||
return "out";
|
||||
case StorageClass::kUniform:
|
||||
return "uniform";
|
||||
case StorageClass::kWorkgroup:
|
||||
return "workgroup";
|
||||
case StorageClass::kHandle:
|
||||
return "handle";
|
||||
case StorageClass::kStorage:
|
||||
return "storage";
|
||||
case StorageClass::kPrivate:
|
||||
return "private";
|
||||
case StorageClass::kFunction:
|
||||
return "function";
|
||||
/// ParseStorageClass parses a StorageClass from a string.
|
||||
/// @param str the string to parse
|
||||
/// @returns the parsed enum, or StorageClass::kInvalid if the string could not be parsed.
|
||||
StorageClass ParseStorageClass(std::string_view str) {
|
||||
if (str == "function") {
|
||||
return StorageClass::kFunction;
|
||||
}
|
||||
return "<unknown>";
|
||||
if (str == "private") {
|
||||
return StorageClass::kPrivate;
|
||||
}
|
||||
if (str == "workgroup") {
|
||||
return StorageClass::kWorkgroup;
|
||||
}
|
||||
if (str == "uniform") {
|
||||
return StorageClass::kUniform;
|
||||
}
|
||||
if (str == "storage") {
|
||||
return StorageClass::kStorage;
|
||||
}
|
||||
return StorageClass::kInvalid;
|
||||
}
|
||||
std::ostream& operator<<(std::ostream& out, StorageClass sc) {
|
||||
out << ToString(sc);
|
||||
return out;
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, StorageClass value) {
|
||||
switch (value) {
|
||||
case StorageClass::kInvalid:
|
||||
return out << "invalid";
|
||||
case StorageClass::kNone:
|
||||
return out << "none";
|
||||
case StorageClass::kFunction:
|
||||
return out << "function";
|
||||
case StorageClass::kPrivate:
|
||||
return out << "private";
|
||||
case StorageClass::kWorkgroup:
|
||||
return out << "workgroup";
|
||||
case StorageClass::kUniform:
|
||||
return out << "uniform";
|
||||
case StorageClass::kStorage:
|
||||
return out << "storage";
|
||||
case StorageClass::kHandle:
|
||||
return out << "handle";
|
||||
case StorageClass::kIn:
|
||||
return out << "in";
|
||||
case StorageClass::kOut:
|
||||
return out << "out";
|
||||
}
|
||||
return out << "<unknown>";
|
||||
}
|
||||
|
||||
} // namespace tint::ast
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020 The Tint Authors.
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -21,18 +21,28 @@ namespace tint::ast {
|
|||
|
||||
/// Storage class of a given pointer.
|
||||
enum class StorageClass {
|
||||
kInvalid = -1,
|
||||
kInvalid,
|
||||
kNone,
|
||||
kInput,
|
||||
kOutput,
|
||||
kUniform,
|
||||
kWorkgroup,
|
||||
kHandle,
|
||||
kStorage,
|
||||
kFunction,
|
||||
kPrivate,
|
||||
kFunction
|
||||
kWorkgroup,
|
||||
kUniform,
|
||||
kStorage,
|
||||
kHandle,
|
||||
kIn,
|
||||
kOut,
|
||||
};
|
||||
|
||||
/// @param out the std::ostream to write to
|
||||
/// @param sc the StorageClass
|
||||
/// @return the std::ostream so calls can be chained
|
||||
std::ostream& operator<<(std::ostream& out, StorageClass sc);
|
||||
|
||||
/// ParseStorageClass parses a StorageClass from a string.
|
||||
/// @param str the string to parse
|
||||
/// @returns the parsed enum, or StorageClass::kInvalid if the string could not be parsed.
|
||||
StorageClass ParseStorageClass(std::string_view str);
|
||||
|
||||
/// @returns true if the StorageClass is host-shareable
|
||||
/// @param sc the StorageClass
|
||||
/// @see https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable
|
||||
|
@ -40,15 +50,6 @@ inline bool IsHostShareable(StorageClass sc) {
|
|||
return sc == ast::StorageClass::kUniform || sc == ast::StorageClass::kStorage;
|
||||
}
|
||||
|
||||
/// @param sc the StorageClass
|
||||
/// @return the name of the given storage class
|
||||
const char* ToString(StorageClass sc);
|
||||
|
||||
/// @param out the std::ostream to write to
|
||||
/// @param sc the StorageClass
|
||||
/// @return the std::ostream so calls can be chained
|
||||
std::ostream& operator<<(std::ostream& out, StorageClass sc);
|
||||
|
||||
} // namespace tint::ast
|
||||
|
||||
#endif // SRC_TINT_AST_STORAGE_CLASS_H_
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "src/tint/sem/vector.h"
|
||||
#include "src/tint/sem/void.h"
|
||||
#include "src/tint/utils/math.h"
|
||||
#include "src/tint/utils/string.h"
|
||||
#include "src/tint/utils/unique_vector.h"
|
||||
|
||||
namespace tint::inspector {
|
||||
|
@ -570,7 +571,7 @@ std::vector<std::string> Inspector::GetUsedExtensionNames() {
|
|||
std::vector<std::string> out;
|
||||
out.reserve(extensions.size());
|
||||
for (auto ext : extensions) {
|
||||
out.push_back(ast::str(ext));
|
||||
out.push_back(utils::ToString(ext));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
@ -582,7 +583,7 @@ std::vector<std::pair<std::string, Source>> Inspector::GetEnableDirectives() {
|
|||
auto global_decls = program_->AST().GlobalDeclarations();
|
||||
for (auto* node : global_decls) {
|
||||
if (auto* ext = node->As<ast::Enable>()) {
|
||||
result.push_back({ast::str(ext->extension), ext->source});
|
||||
result.push_back({utils::ToString(ext->extension), ext->source});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,9 +39,9 @@ ast::PipelineStage EnumConverter::ToPipelineStage(SpvExecutionModel model) {
|
|||
ast::StorageClass EnumConverter::ToStorageClass(const SpvStorageClass sc) {
|
||||
switch (sc) {
|
||||
case SpvStorageClassInput:
|
||||
return ast::StorageClass::kInput;
|
||||
return ast::StorageClass::kIn;
|
||||
case SpvStorageClassOutput:
|
||||
return ast::StorageClass::kOutput;
|
||||
return ast::StorageClass::kOut;
|
||||
case SpvStorageClassUniform:
|
||||
return ast::StorageClass::kUniform;
|
||||
case SpvStorageClassWorkgroup:
|
||||
|
|
|
@ -125,8 +125,8 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
EnumConverterGood,
|
||||
SpvStorageClassTest,
|
||||
testing::Values(
|
||||
StorageClassCase{SpvStorageClassInput, true, ast::StorageClass::kInput},
|
||||
StorageClassCase{SpvStorageClassOutput, true, ast::StorageClass::kOutput},
|
||||
StorageClassCase{SpvStorageClassInput, true, ast::StorageClass::kIn},
|
||||
StorageClassCase{SpvStorageClassOutput, true, ast::StorageClass::kOut},
|
||||
StorageClassCase{SpvStorageClassUniform, true, ast::StorageClass::kUniform},
|
||||
StorageClassCase{SpvStorageClassWorkgroup, true, ast::StorageClass::kWorkgroup},
|
||||
StorageClassCase{SpvStorageClassUniformConstant, true, ast::StorageClass::kNone},
|
||||
|
|
|
@ -1219,8 +1219,8 @@ const Type* ParserImpl::ConvertType(uint32_t type_id,
|
|||
}
|
||||
|
||||
// Pipeline input and output variables map to private variables.
|
||||
if (ast_storage_class == ast::StorageClass::kInput ||
|
||||
ast_storage_class == ast::StorageClass::kOutput) {
|
||||
if (ast_storage_class == ast::StorageClass::kIn ||
|
||||
ast_storage_class == ast::StorageClass::kOut) {
|
||||
ast_storage_class = ast::StorageClass::kPrivate;
|
||||
}
|
||||
switch (ptr_as) {
|
||||
|
@ -1446,8 +1446,8 @@ bool ParserImpl::EmitModuleScopeVariables() {
|
|||
}
|
||||
switch (enum_converter_.ToStorageClass(spirv_storage_class)) {
|
||||
case ast::StorageClass::kNone:
|
||||
case ast::StorageClass::kInput:
|
||||
case ast::StorageClass::kOutput:
|
||||
case ast::StorageClass::kIn:
|
||||
case ast::StorageClass::kOut:
|
||||
case ast::StorageClass::kUniform:
|
||||
case ast::StorageClass::kHandle:
|
||||
case ast::StorageClass::kStorage:
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
#include "src/tint/utils/map.h"
|
||||
#include "src/tint/utils/string.h"
|
||||
#include "src/tint/utils/unique_allocator.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Type);
|
||||
|
@ -518,13 +519,13 @@ std::string I32::String() const {
|
|||
|
||||
std::string Pointer::String() const {
|
||||
std::stringstream ss;
|
||||
ss << "ptr<" << std::string(ast::ToString(storage_class)) << ", " << type->String() + ">";
|
||||
ss << "ptr<" << utils::ToString(storage_class) << ", " << type->String() + ">";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string Reference::String() const {
|
||||
std::stringstream ss;
|
||||
ss << "ref<" + std::string(ast::ToString(storage_class)) << ", " << type->String() << ">";
|
||||
ss << "ref<" + utils::ToString(storage_class) << ", " << type->String() << ">";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ TEST(SpvParserTypeTest, DifferentArgumentsGivesDifferentPointer) {
|
|||
EXPECT_NE(ty.Pointer(ty.I32(), ast::StorageClass::kNone),
|
||||
ty.Pointer(ty.U32(), ast::StorageClass::kNone));
|
||||
EXPECT_NE(ty.Pointer(ty.I32(), ast::StorageClass::kNone),
|
||||
ty.Pointer(ty.I32(), ast::StorageClass::kInput));
|
||||
ty.Pointer(ty.I32(), ast::StorageClass::kIn));
|
||||
EXPECT_NE(ty.Vector(ty.I32(), 3), ty.Vector(ty.U32(), 3));
|
||||
EXPECT_NE(ty.Vector(ty.I32(), 3), ty.Vector(ty.I32(), 2));
|
||||
EXPECT_NE(ty.Matrix(ty.I32(), 3, 2), ty.Matrix(ty.U32(), 3, 2));
|
||||
|
|
|
@ -400,7 +400,7 @@ Maybe<bool> ParserImpl::enable_directive() {
|
|||
synchronized_ = true;
|
||||
next();
|
||||
name = {"f16", t.source()};
|
||||
} else if (t.Is(Token::Type::kParenLeft)){
|
||||
} else if (t.Is(Token::Type::kParenLeft)) {
|
||||
// A common error case is writing `enable(foo);` instead of `enable foo;`.
|
||||
synchronized_ = false;
|
||||
return add_error(t.source(), "enable directives don't take parenthesis");
|
||||
|
@ -1315,28 +1315,12 @@ Expect<ast::StorageClass> ParserImpl::expect_storage_class(std::string_view use)
|
|||
return Failure::kErrored;
|
||||
}
|
||||
|
||||
auto name = ident.value;
|
||||
if (name == "uniform") {
|
||||
return {ast::StorageClass::kUniform, t.source()};
|
||||
auto storage_class = ast::ParseStorageClass(ident.value);
|
||||
if (storage_class == ast::StorageClass::kInvalid) {
|
||||
return add_error(t.source(), "invalid storage class", use);
|
||||
}
|
||||
|
||||
if (name == "workgroup") {
|
||||
return {ast::StorageClass::kWorkgroup, t.source()};
|
||||
}
|
||||
|
||||
if (name == "storage" || name == "storage_buffer") {
|
||||
return {ast::StorageClass::kStorage, t.source()};
|
||||
}
|
||||
|
||||
if (name == "private") {
|
||||
return {ast::StorageClass::kPrivate, t.source()};
|
||||
}
|
||||
|
||||
if (name == "function") {
|
||||
return {ast::StorageClass::kFunction, t.source()};
|
||||
}
|
||||
|
||||
return add_error(t.source(), "invalid storage class", use);
|
||||
return {storage_class, t.source()};
|
||||
}
|
||||
|
||||
// struct_decl
|
||||
|
|
|
@ -46,7 +46,6 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
testing::Values(StorageClassData{"uniform", ast::StorageClass::kUniform},
|
||||
StorageClassData{"workgroup", ast::StorageClass::kWorkgroup},
|
||||
StorageClassData{"storage", ast::StorageClass::kStorage},
|
||||
StorageClassData{"storage_buffer", ast::StorageClass::kStorage},
|
||||
StorageClassData{"private", ast::StorageClass::kPrivate},
|
||||
StorageClassData{"function", ast::StorageClass::kFunction}));
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
VariableStorageData{"uniform", ast::StorageClass::kUniform, ast::Access::kUndefined},
|
||||
VariableStorageData{"workgroup", ast::StorageClass::kWorkgroup, ast::Access::kUndefined},
|
||||
VariableStorageData{"storage", ast::StorageClass::kStorage, ast::Access::kUndefined},
|
||||
VariableStorageData{"storage_buffer", ast::StorageClass::kStorage, ast::Access::kUndefined},
|
||||
VariableStorageData{"private", ast::StorageClass::kPrivate, ast::Access::kUndefined},
|
||||
VariableStorageData{"function", ast::StorageClass::kFunction, ast::Access::kUndefined},
|
||||
VariableStorageData{"storage, read", ast::StorageClass::kStorage, ast::Access::kRead},
|
||||
|
|
|
@ -807,8 +807,8 @@ TEST_P(ResolverFunctionParameterValidationTest, StorageClass) {
|
|||
INSTANTIATE_TEST_SUITE_P(ResolverTest,
|
||||
ResolverFunctionParameterValidationTest,
|
||||
testing::Values(TestParams{ast::StorageClass::kNone, false},
|
||||
TestParams{ast::StorageClass::kInput, false},
|
||||
TestParams{ast::StorageClass::kOutput, false},
|
||||
TestParams{ast::StorageClass::kIn, false},
|
||||
TestParams{ast::StorageClass::kOut, false},
|
||||
TestParams{ast::StorageClass::kUniform, false},
|
||||
TestParams{ast::StorageClass::kWorkgroup, true},
|
||||
TestParams{ast::StorageClass::kHandle, false},
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
#include "src/tint/utils/math.h"
|
||||
#include "src/tint/utils/reverse.h"
|
||||
#include "src/tint/utils/scoped_assignment.h"
|
||||
#include "src/tint/utils/string.h"
|
||||
#include "src/tint/utils/transform.h"
|
||||
|
||||
namespace tint::resolver {
|
||||
|
@ -344,7 +345,7 @@ bool Validator::VariableInitializer(const ast::Variable* v,
|
|||
// https://gpuweb.github.io/gpuweb/wgsl/#var-and-let
|
||||
// Optionally has an initializer expression, if the variable is in the
|
||||
// private or function storage classes.
|
||||
AddError("var of storage class '" + std::string(ast::ToString(storage_class)) +
|
||||
AddError("var of storage class '" + utils::ToString(storage_class) +
|
||||
"' cannot have an initializer. var initializers are only "
|
||||
"supported for the storage classes "
|
||||
"'private' and 'function'",
|
||||
|
@ -396,9 +397,9 @@ bool Validator::StorageClassLayout(const sem::Type* store_ty,
|
|||
// TODO(tint:1473, tint:1502): Remove this error after f16 is supported in "uniform" and
|
||||
// "storage" storage class.
|
||||
if (Is<sem::F16>(sem::Type::DeepestElementOf(store_ty))) {
|
||||
AddError("using f16 types in '" + std::string(ast::ToString(sc)) +
|
||||
"' storage class is not implemented yet",
|
||||
source);
|
||||
AddError(
|
||||
"using f16 types in '" + utils::ToString(sc) + "' storage class is not implemented yet",
|
||||
source);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -418,7 +419,7 @@ bool Validator::StorageClassLayout(const sem::Type* store_ty,
|
|||
if (m->Offset() % required_align != 0) {
|
||||
AddError("the offset of a struct member of type '" +
|
||||
m->Type()->UnwrapRef()->FriendlyName(symbols_) +
|
||||
"' in storage class '" + ast::ToString(sc) +
|
||||
"' in storage class '" + utils::ToString(sc) +
|
||||
"' must be a multiple of " + std::to_string(required_align) +
|
||||
" bytes, but '" + member_name_of(m) + "' is currently at offset " +
|
||||
std::to_string(m->Offset()) + ". Consider setting @align(" +
|
||||
|
@ -583,8 +584,8 @@ bool Validator::GlobalVariable(
|
|||
bool is_shader_io_attribute =
|
||||
attr->IsAnyOf<ast::BuiltinAttribute, ast::InterpolateAttribute,
|
||||
ast::InvariantAttribute, ast::LocationAttribute>();
|
||||
bool has_io_storage_class = global->StorageClass() == ast::StorageClass::kInput ||
|
||||
global->StorageClass() == ast::StorageClass::kOutput;
|
||||
bool has_io_storage_class = global->StorageClass() == ast::StorageClass::kIn ||
|
||||
global->StorageClass() == ast::StorageClass::kOut;
|
||||
if (!attr->IsAnyOf<ast::BindingAttribute, ast::GroupAttribute,
|
||||
ast::InternalAttribute>() &&
|
||||
(!is_shader_io_attribute || !has_io_storage_class)) {
|
||||
|
@ -740,8 +741,8 @@ bool Validator::Var(const sem::Variable* v) const {
|
|||
}
|
||||
|
||||
if (IsValidationEnabled(var->attributes, ast::DisabledValidation::kIgnoreStorageClass) &&
|
||||
(var->declared_storage_class == ast::StorageClass::kInput ||
|
||||
var->declared_storage_class == ast::StorageClass::kOutput)) {
|
||||
(var->declared_storage_class == ast::StorageClass::kIn ||
|
||||
var->declared_storage_class == ast::StorageClass::kOut)) {
|
||||
AddError("invalid use of input/output storage class", var->source);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/sem/function.h"
|
||||
#include "src/tint/sem/variable.h"
|
||||
#include "src/tint/utils/string.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::BindingRemapper);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::BindingRemapper::Remappings);
|
||||
|
@ -125,7 +126,7 @@ void BindingRemapper::Run(CloneContext& ctx, const DataMap& inputs, DataMap&) co
|
|||
ctx.dst->Diagnostics().add_error(
|
||||
diag::System::Transform,
|
||||
"cannot apply access control to variable with storage class " +
|
||||
std::string(ast::ToString(sem->StorageClass())));
|
||||
std::string(utils::ToString(sem->StorageClass())));
|
||||
return;
|
||||
}
|
||||
auto* ty = sem->Type()->UnwrapRef();
|
||||
|
|
|
@ -181,7 +181,7 @@ struct CanonicalizeEntryPointIO::State {
|
|||
auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(attributes);
|
||||
if (cfg.shader_style == ShaderStyle::kGlsl && builtin) {
|
||||
name = GLSLBuiltinToString(builtin->builtin, func_ast->PipelineStage(),
|
||||
ast::StorageClass::kInput);
|
||||
ast::StorageClass::kIn);
|
||||
}
|
||||
auto symbol = ctx.dst->Symbols().New(name);
|
||||
|
||||
|
@ -198,7 +198,7 @@ struct CanonicalizeEntryPointIO::State {
|
|||
value = ctx.dst->IndexAccessor(value, 0_i);
|
||||
}
|
||||
}
|
||||
ctx.dst->GlobalVar(symbol, ast_type, ast::StorageClass::kInput, std::move(attributes));
|
||||
ctx.dst->GlobalVar(symbol, ast_type, ast::StorageClass::kIn, std::move(attributes));
|
||||
return value;
|
||||
} else if (cfg.shader_style == ShaderStyle::kMsl &&
|
||||
ast::HasAttribute<ast::BuiltinAttribute>(attributes)) {
|
||||
|
@ -246,7 +246,7 @@ struct CanonicalizeEntryPointIO::State {
|
|||
if (cfg.shader_style == ShaderStyle::kGlsl) {
|
||||
if (auto* b = ast::GetAttribute<ast::BuiltinAttribute>(attributes)) {
|
||||
name = GLSLBuiltinToString(b->builtin, func_ast->PipelineStage(),
|
||||
ast::StorageClass::kOutput);
|
||||
ast::StorageClass::kOut);
|
||||
value = ToGLSLBuiltin(b->builtin, value, type);
|
||||
}
|
||||
}
|
||||
|
@ -463,7 +463,7 @@ struct CanonicalizeEntryPointIO::State {
|
|||
type = ctx.dst->ty.array(type, 1_u);
|
||||
lhs = ctx.dst->IndexAccessor(lhs, 0_i);
|
||||
}
|
||||
ctx.dst->GlobalVar(name, type, ast::StorageClass::kOutput, std::move(attributes));
|
||||
ctx.dst->GlobalVar(name, type, ast::StorageClass::kOut, std::move(attributes));
|
||||
wrapper_body.push_back(ctx.dst->Assign(lhs, outval.value));
|
||||
}
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ struct CanonicalizeEntryPointIO::State {
|
|||
case ast::Builtin::kSampleIndex:
|
||||
return "gl_SampleID";
|
||||
case ast::Builtin::kSampleMask:
|
||||
if (storage_class == ast::StorageClass::kInput) {
|
||||
if (storage_class == ast::StorageClass::kIn) {
|
||||
return "gl_SampleMaskIn";
|
||||
} else {
|
||||
return "gl_SampleMask";
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef SRC_TINT_UTILS_STRING_H_
|
||||
#define SRC_TINT_UTILS_STRING_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace tint::utils {
|
||||
|
@ -34,6 +35,15 @@ inline std::string ReplaceAll(std::string str,
|
|||
return str;
|
||||
}
|
||||
|
||||
/// @param value the value to be printed as a string
|
||||
/// @returns value printed as a string via the std::ostream `<<` operator
|
||||
template <typename T>
|
||||
std::string ToString(const T& value) {
|
||||
std::stringstream s;
|
||||
s << value;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
} // namespace tint::utils
|
||||
|
||||
#endif // SRC_TINT_UTILS_STRING_H_
|
||||
|
|
|
@ -32,5 +32,10 @@ TEST(StringTest, ReplaceAll) {
|
|||
ASSERT_EQ("aabxybbxybcc", ReplaceAll("aabbcc", "b", "bxyb"));
|
||||
}
|
||||
|
||||
TEST(StringTest, ToString) {
|
||||
ASSERT_EQ("123", ToString(123));
|
||||
ASSERT_EQ("hello", ToString("hello"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::utils
|
||||
|
|
|
@ -1929,8 +1929,8 @@ bool GeneratorImpl::EmitGlobalVariable(const ast::Variable* global) {
|
|||
return EmitPrivateVariable(sem);
|
||||
case ast::StorageClass::kWorkgroup:
|
||||
return EmitWorkgroupVariable(sem);
|
||||
case ast::StorageClass::kInput:
|
||||
case ast::StorageClass::kOutput:
|
||||
case ast::StorageClass::kIn:
|
||||
case ast::StorageClass::kOut:
|
||||
return EmitIOVariable(sem);
|
||||
default:
|
||||
TINT_ICE(Writer, diagnostics_)
|
||||
|
@ -2738,11 +2738,11 @@ bool GeneratorImpl::EmitType(std::ostream& out,
|
|||
*name_printed = false;
|
||||
}
|
||||
switch (storage_class) {
|
||||
case ast::StorageClass::kInput: {
|
||||
case ast::StorageClass::kIn: {
|
||||
out << "in ";
|
||||
break;
|
||||
}
|
||||
case ast::StorageClass::kOutput: {
|
||||
case ast::StorageClass::kOut: {
|
||||
out << "out ";
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ TEST_F(GlslGeneratorImplTest, GenerateSampleIndexES) {
|
|||
Builtin(ast::Builtin::kSampleIndex),
|
||||
Disable(ast::DisabledValidation::kIgnoreStorageClass),
|
||||
},
|
||||
ast::StorageClass::kInput);
|
||||
ast::StorageClass::kIn);
|
||||
Func("my_func", {}, ty.i32(),
|
||||
{
|
||||
Return(Expr("gl_SampleID")),
|
||||
|
@ -87,7 +87,7 @@ TEST_F(GlslGeneratorImplTest, GenerateSampleIndexDesktop) {
|
|||
Builtin(ast::Builtin::kSampleIndex),
|
||||
Disable(ast::DisabledValidation::kIgnoreStorageClass),
|
||||
},
|
||||
ast::StorageClass::kInput);
|
||||
ast::StorageClass::kIn);
|
||||
Func("my_func", {}, ty.i32(),
|
||||
{
|
||||
Return(Expr("gl_SampleID")),
|
||||
|
|
|
@ -477,8 +477,8 @@ bool Builder::GenerateEntryPoint(const ast::Function* func, uint32_t id) {
|
|||
for (const auto* var : func_sem->TransitivelyReferencedGlobals()) {
|
||||
// For SPIR-V 1.3 we only output Input/output variables. If we update to
|
||||
// SPIR-V 1.4 or later this should be all variables.
|
||||
if (var->StorageClass() != ast::StorageClass::kInput &&
|
||||
var->StorageClass() != ast::StorageClass::kOutput) {
|
||||
if (var->StorageClass() != ast::StorageClass::kIn &&
|
||||
var->StorageClass() != ast::StorageClass::kOut) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -856,7 +856,7 @@ bool Builder::GenerateGlobalVariable(const ast::Variable* v) {
|
|||
// VK_KHR_zero_initialize_workgroup_memory extension is enabled, we should
|
||||
// also zero-initialize.
|
||||
if (sem->StorageClass() == ast::StorageClass::kPrivate ||
|
||||
sem->StorageClass() == ast::StorageClass::kOutput ||
|
||||
sem->StorageClass() == ast::StorageClass::kOut ||
|
||||
(zero_initialize_workgroup_memory_ &&
|
||||
sem->StorageClass() == ast::StorageClass::kWorkgroup)) {
|
||||
init_id = GenerateConstantNullIfNeeded(type);
|
||||
|
@ -4113,9 +4113,9 @@ SpvStorageClass Builder::ConvertStorageClass(ast::StorageClass klass) const {
|
|||
switch (klass) {
|
||||
case ast::StorageClass::kInvalid:
|
||||
return SpvStorageClassMax;
|
||||
case ast::StorageClass::kInput:
|
||||
case ast::StorageClass::kIn:
|
||||
return SpvStorageClassInput;
|
||||
case ast::StorageClass::kOutput:
|
||||
case ast::StorageClass::kOut:
|
||||
return SpvStorageClassOutput;
|
||||
case ast::StorageClass::kUniform:
|
||||
return SpvStorageClassUniform;
|
||||
|
@ -4138,9 +4138,9 @@ SpvStorageClass Builder::ConvertStorageClass(ast::StorageClass klass) const {
|
|||
SpvBuiltIn Builder::ConvertBuiltin(ast::Builtin builtin, ast::StorageClass storage) {
|
||||
switch (builtin) {
|
||||
case ast::Builtin::kPosition:
|
||||
if (storage == ast::StorageClass::kInput) {
|
||||
if (storage == ast::StorageClass::kIn) {
|
||||
return SpvBuiltInFragCoord;
|
||||
} else if (storage == ast::StorageClass::kOutput) {
|
||||
} else if (storage == ast::StorageClass::kOut) {
|
||||
return SpvBuiltInPosition;
|
||||
} else {
|
||||
TINT_ICE(Writer, builder_.Diagnostics()) << "invalid storage class for builtin";
|
||||
|
|
|
@ -443,29 +443,27 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
BuiltinDataTest,
|
||||
testing::Values(
|
||||
BuiltinData{ast::Builtin::kNone, ast::StorageClass::kNone, SpvBuiltInMax},
|
||||
BuiltinData{ast::Builtin::kPosition, ast::StorageClass::kInput, SpvBuiltInFragCoord},
|
||||
BuiltinData{ast::Builtin::kPosition, ast::StorageClass::kOutput, SpvBuiltInPosition},
|
||||
BuiltinData{ast::Builtin::kPosition, ast::StorageClass::kIn, SpvBuiltInFragCoord},
|
||||
BuiltinData{ast::Builtin::kPosition, ast::StorageClass::kOut, SpvBuiltInPosition},
|
||||
BuiltinData{
|
||||
ast::Builtin::kVertexIndex,
|
||||
ast::StorageClass::kInput,
|
||||
ast::StorageClass::kIn,
|
||||
SpvBuiltInVertexIndex,
|
||||
},
|
||||
BuiltinData{ast::Builtin::kInstanceIndex, ast::StorageClass::kInput,
|
||||
SpvBuiltInInstanceIndex},
|
||||
BuiltinData{ast::Builtin::kFrontFacing, ast::StorageClass::kInput, SpvBuiltInFrontFacing},
|
||||
BuiltinData{ast::Builtin::kFragDepth, ast::StorageClass::kOutput, SpvBuiltInFragDepth},
|
||||
BuiltinData{ast::Builtin::kLocalInvocationId, ast::StorageClass::kInput,
|
||||
BuiltinData{ast::Builtin::kInstanceIndex, ast::StorageClass::kIn, SpvBuiltInInstanceIndex},
|
||||
BuiltinData{ast::Builtin::kFrontFacing, ast::StorageClass::kIn, SpvBuiltInFrontFacing},
|
||||
BuiltinData{ast::Builtin::kFragDepth, ast::StorageClass::kOut, SpvBuiltInFragDepth},
|
||||
BuiltinData{ast::Builtin::kLocalInvocationId, ast::StorageClass::kIn,
|
||||
SpvBuiltInLocalInvocationId},
|
||||
BuiltinData{ast::Builtin::kLocalInvocationIndex, ast::StorageClass::kInput,
|
||||
BuiltinData{ast::Builtin::kLocalInvocationIndex, ast::StorageClass::kIn,
|
||||
SpvBuiltInLocalInvocationIndex},
|
||||
BuiltinData{ast::Builtin::kGlobalInvocationId, ast::StorageClass::kInput,
|
||||
BuiltinData{ast::Builtin::kGlobalInvocationId, ast::StorageClass::kIn,
|
||||
SpvBuiltInGlobalInvocationId},
|
||||
BuiltinData{ast::Builtin::kWorkgroupId, ast::StorageClass::kInput, SpvBuiltInWorkgroupId},
|
||||
BuiltinData{ast::Builtin::kNumWorkgroups, ast::StorageClass::kInput,
|
||||
SpvBuiltInNumWorkgroups},
|
||||
BuiltinData{ast::Builtin::kSampleIndex, ast::StorageClass::kInput, SpvBuiltInSampleId},
|
||||
BuiltinData{ast::Builtin::kSampleMask, ast::StorageClass::kInput, SpvBuiltInSampleMask},
|
||||
BuiltinData{ast::Builtin::kSampleMask, ast::StorageClass::kOutput, SpvBuiltInSampleMask}));
|
||||
BuiltinData{ast::Builtin::kWorkgroupId, ast::StorageClass::kIn, SpvBuiltInWorkgroupId},
|
||||
BuiltinData{ast::Builtin::kNumWorkgroups, ast::StorageClass::kIn, SpvBuiltInNumWorkgroups},
|
||||
BuiltinData{ast::Builtin::kSampleIndex, ast::StorageClass::kIn, SpvBuiltInSampleId},
|
||||
BuiltinData{ast::Builtin::kSampleMask, ast::StorageClass::kIn, SpvBuiltInSampleMask},
|
||||
BuiltinData{ast::Builtin::kSampleMask, ast::StorageClass::kOut, SpvBuiltInSampleMask}));
|
||||
|
||||
TEST_F(BuilderTest, GlobalVar_DeclReadOnly) {
|
||||
// struct A {
|
||||
|
|
|
@ -299,7 +299,7 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedF16Matrix) {
|
|||
|
||||
TEST_F(BuilderTest_Type, GeneratePtr) {
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* ptr = create<sem::Pointer>(i32, ast::StorageClass::kOutput, ast::Access::kReadWrite);
|
||||
auto* ptr = create<sem::Pointer>(i32, ast::StorageClass::kOut, ast::Access::kReadWrite);
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
|
@ -314,7 +314,7 @@ TEST_F(BuilderTest_Type, GeneratePtr) {
|
|||
|
||||
TEST_F(BuilderTest_Type, ReturnsGeneratedPtr) {
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* ptr = create<sem::Pointer>(i32, ast::StorageClass::kOutput, ast::Access::kReadWrite);
|
||||
auto* ptr = create<sem::Pointer>(i32, ast::StorageClass::kOut, ast::Access::kReadWrite);
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
|
@ -601,8 +601,8 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
BuilderTest_Type,
|
||||
PtrDataTest,
|
||||
testing::Values(PtrData{ast::StorageClass::kNone, SpvStorageClassMax},
|
||||
PtrData{ast::StorageClass::kInput, SpvStorageClassInput},
|
||||
PtrData{ast::StorageClass::kOutput, SpvStorageClassOutput},
|
||||
PtrData{ast::StorageClass::kIn, SpvStorageClassInput},
|
||||
PtrData{ast::StorageClass::kOut, SpvStorageClassOutput},
|
||||
PtrData{ast::StorageClass::kUniform, SpvStorageClassUniform},
|
||||
PtrData{ast::StorageClass::kWorkgroup, SpvStorageClassWorkgroup},
|
||||
PtrData{ast::StorageClass::kHandle, SpvStorageClassUniformConstant},
|
||||
|
|
|
@ -16,7 +16,7 @@ struct PointLight {
|
|||
};
|
||||
|
||||
@binding(0) @group(0) var<uniform> uniforms : Uniforms;
|
||||
@binding(1) @group(0) var<storage_buffer, read> pointLights : PointLights;
|
||||
@binding(1) @group(0) var<storage, read> pointLights : PointLights;
|
||||
@binding(2) @group(0) var mySampler: sampler;
|
||||
@binding(3) @group(0) var myTexture: texture_2d<f32>;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
};
|
||||
@group(0) @binding(0) var src : texture_2d<f32>;
|
||||
@group(0) @binding(1) var dst : texture_2d<f32>;
|
||||
@group(0) @binding(2) var<storage_buffer, read_write> output : OutputBuf;
|
||||
@group(0) @binding(2) var<storage, read_write> output : OutputBuf;
|
||||
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
||||
//@builtin(global_invocation_id) var<in> GlobalInvocationID : vec3<u32>;
|
||||
// Fp16 logic
|
||||
|
|
Loading…
Reference in New Issue