wgsl: Deprecate [[access]] decorations

Handle access control on var declarations instead of via [[access]]
decorations. This change does the minimal work to migrate the WGSL
parser over to the new syntax. Additional changes will be needed
to correctly generate defaulted access qualifiers, as well as
validating access usage.

The [[access]] decorations are still supported by the WGSL parser,
with new deprecated warnings, but not for aliases. Example:
   var x : [[access(x)]] alias_to_struct;

Making this work is far more effort than I want to dedicate to backwards
compatibility, and I do not beleive any real-world usage will be doing
this.

Still TODO:
* Adding access control as the optional, third parameter to ptr<>.
* Calculating default accesses for the various storage types.
* Validating usage of variables against the different accesses.

Bug: tint:846
Change-Id: If8ca82e5d16ec319ecd01f9a2cafffd930963bde
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/53088
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2021-06-04 20:41:47 +00:00 committed by Tint LUCI CQ
parent b175d91c7e
commit 93e8f527ee
450 changed files with 2651 additions and 2213 deletions

View File

@ -96,21 +96,21 @@ analysis, but can also greatly aid simple diagnostics like symbol collision erro
**Don't:** **Don't:**
``` ```
shader.wgsl:7:1 error: the originating variable of the left-hand side must not have an access(read) access attribute. shader.wgsl:7:1 error: the originating variable of the left-hand side of an assignment expression must not be declared with read access control.
``` ```
**Do:** **Do:**
``` ```
shader.wgsl:7:1 error: cannot assign to variable with [[access(read)]] decoration shader.wgsl:7:1 error: cannot assign to variable with read access control
x = 1; x.y = 1;
^ ^^^^^^^
shader.wgsl:2:8 note: [[access(read)]] declared here shader.wgsl:2:8 note: read access control declared here
var x : [[access(read)]] i32; var<storage, read> x : i32;
^^^^^^^^^^^^^^^^ ^^^^
``` ```
**Justification:** **Justification:**

View File

@ -101,20 +101,19 @@ void ExtractBindingRemapperInputs(Reader* r, tint::transform::DataMap* inputs) {
uint8_t old_binding; uint8_t old_binding;
uint8_t new_group; uint8_t new_group;
uint8_t new_binding; uint8_t new_binding;
ast::AccessControl::Access new_ac; ast::Access new_access;
}; };
std::vector<Config> configs = r->vector<Config>(); std::vector<Config> configs = r->vector<Config>();
transform::BindingRemapper::BindingPoints binding_points; transform::BindingRemapper::BindingPoints binding_points;
transform::BindingRemapper::AccessControls access_controls; transform::BindingRemapper::Accesses accesses;
for (const auto& config : configs) { for (const auto& config : configs) {
binding_points[{config.old_binding, config.old_group}] = { binding_points[{config.old_binding, config.old_group}] = {
config.new_binding, config.new_group}; config.new_binding, config.new_group};
access_controls[{config.old_binding, config.old_group}] = config.new_ac; accesss[{config.old_binding, config.old_group}] = config.new_access;
} }
inputs->Add<transform::BindingRemapper::Remappings>(binding_points, inputs->Add<transform::BindingRemapper::Remappings>(binding_points, accesss);
access_controls);
} }
void ExtractFirstIndexOffsetInputs(Reader* r, void ExtractFirstIndexOffsetInputs(Reader* r,

View File

@ -292,8 +292,8 @@ template("libtint_source_set") {
libtint_source_set("libtint_core_all_src") { libtint_source_set("libtint_core_all_src") {
sources = [ sources = [
"ast/access_control.cc", "ast/access.cc",
"ast/access_control.h", "ast/access.h",
"ast/access_decoration.cc", "ast/access_decoration.cc",
"ast/access_decoration.h", "ast/access_decoration.h",
"ast/alias.cc", "ast/alias.cc",

View File

@ -38,8 +38,8 @@ endfunction()
set(TINT_LIB_SRCS set(TINT_LIB_SRCS
../include/tint/tint.h ../include/tint/tint.h
ast/access_control.cc ast/access.cc
ast/access_control.h ast/access.h
ast/access_decoration.cc ast/access_decoration.cc
ast/access_decoration.h ast/access_decoration.h
ast/alias.cc ast/alias.cc
@ -496,7 +496,6 @@ endif()
if(${TINT_BUILD_TESTS}) if(${TINT_BUILD_TESTS})
set(TINT_TEST_SRCS set(TINT_TEST_SRCS
ast/access_control_test.cc
ast/access_decoration_test.cc ast/access_decoration_test.cc
ast/alias_test.cc ast/alias_test.cc
ast/array_accessor_expression_test.cc ast/array_accessor_expression_test.cc
@ -748,7 +747,7 @@ if(${TINT_BUILD_TESTS})
reader/wgsl/parser_impl_variable_decoration_test.cc reader/wgsl/parser_impl_variable_decoration_test.cc
reader/wgsl/parser_impl_variable_ident_decl_test.cc reader/wgsl/parser_impl_variable_ident_decl_test.cc
reader/wgsl/parser_impl_variable_stmt_test.cc reader/wgsl/parser_impl_variable_stmt_test.cc
reader/wgsl/parser_impl_variable_storage_decoration_test.cc reader/wgsl/parser_impl_variable_qualifier_test.cc
reader/wgsl/token_test.cc reader/wgsl/token_test.cc
) )
endif() endif()

43
src/ast/access.cc Normal file
View File

@ -0,0 +1,43 @@
// 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/ast/access.h"
namespace tint {
namespace ast {
std::ostream& operator<<(std::ostream& out, Access access) {
switch (access) {
case ast::Access::kUndefined: {
out << "undefined";
break;
}
case ast::Access::kRead: {
out << "read";
break;
}
case ast::Access::kReadWrite: {
out << "read_write";
break;
}
case ast::Access::kWrite: {
out << "write";
break;
}
}
return out;
}
} // namespace ast
} // namespace tint

47
src/ast/access.h Normal file
View File

@ -0,0 +1,47 @@
// 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_AST_ACCESS_H_
#define SRC_AST_ACCESS_H_
#include <ostream>
#include <string>
namespace tint {
namespace ast {
/// The access control settings
enum Access {
/// Not declared in the source
kUndefined,
/// Read only
kRead,
/// Write only
kWrite,
/// Read write
kReadWrite
};
/// @param out the std::ostream to write to
/// @param access the Access
/// @return the std::ostream so calls can be chained
std::ostream& operator<<(std::ostream& out, Access access);
/// [DEPRECATED]: Old name in use by Dawn.
using AccessControl = Access;
} // namespace ast
} // namespace tint
#endif // SRC_AST_ACCESS_H_

View File

@ -1,97 +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/ast/access_control.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::AccessControl);
namespace tint {
namespace ast {
AccessControl::AccessControl(ProgramID program_id,
const Source& source,
Access access,
const Type* subtype)
: Base(program_id, source), access_(access), subtype_(subtype) {
TINT_ASSERT(subtype_);
TINT_ASSERT(!subtype_->Is<AccessControl>());
}
AccessControl::AccessControl(AccessControl&&) = default;
AccessControl::~AccessControl() = default;
std::string AccessControl::type_name() const {
std::string name = "__access_control_";
switch (access_) {
case ast::AccessControl::kRead:
name += "read_only";
break;
case ast::AccessControl::kWrite:
name += "write_only";
break;
case ast::AccessControl::kReadWrite:
name += "read_write";
break;
}
return name + subtype_->type_name();
}
std::string AccessControl::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
out << "[[access(";
switch (access_) {
case ast::AccessControl::kRead:
out << "read";
break;
case ast::AccessControl::kWrite:
out << "write";
break;
case ast::AccessControl::kReadWrite:
out << "read_write";
break;
}
out << ")]] " << subtype_->FriendlyName(symbols);
return out.str();
}
AccessControl* AccessControl::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* ty = ctx->Clone(type());
return ctx->dst->create<AccessControl>(src, access_, ty);
}
std::ostream& operator<<(std::ostream& out, AccessControl::Access access) {
switch (access) {
case ast::AccessControl::kRead: {
out << "read_only";
break;
}
case ast::AccessControl::kReadWrite: {
out << "read_write";
break;
}
case ast::AccessControl::kWrite: {
out << "write_only";
break;
}
}
return out;
}
} // namespace ast
} // namespace tint

View File

@ -1,90 +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_AST_ACCESS_CONTROL_H_
#define SRC_AST_ACCESS_CONTROL_H_
#include <ostream>
#include <string>
#include "src/ast/type.h"
namespace tint {
namespace ast {
/// An access control type. Holds an access setting and pointer to another type.
class AccessControl : public Castable<AccessControl, Type> {
public:
/// The access control settings
enum Access {
/// Read only
kRead,
/// Write only
kWrite,
/// Read write
kReadWrite
};
/// Constructor
/// @param program_id the identifier of the program that owns this node
/// @param source the source of this node
/// @param access the access control setting
/// @param subtype the access controlled type
AccessControl(ProgramID program_id,
const Source& source,
Access access,
const Type* subtype);
/// Move constructor
AccessControl(AccessControl&&);
~AccessControl() override;
/// @returns true if the access control is read only
bool IsReadOnly() const { return access_ == Access::kRead; }
/// @returns true if the access control is write only
bool IsWriteOnly() const { return access_ == Access::kWrite; }
/// @returns true if the access control is read/write
bool IsReadWrite() const { return access_ == Access::kReadWrite; }
/// @returns the access control value
Access access_control() const { return access_; }
/// @returns the subtype type
Type* type() const { return const_cast<Type*>(subtype_); }
/// @returns the name for this type
std::string type_name() const override;
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
AccessControl* Clone(CloneContext* ctx) const override;
private:
Access const access_;
const Type* const subtype_;
};
/// @param out the std::ostream to write to
/// @param access the AccessControl
/// @return the std::ostream so calls can be chained
std::ostream& operator<<(std::ostream& out, AccessControl::Access access);
} // namespace ast
} // namespace tint
#endif // SRC_AST_ACCESS_CONTROL_H_

View File

@ -1,94 +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/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint {
namespace ast {
namespace {
using AstAccessControlTest = TestHelper;
TEST_F(AstAccessControlTest, Create) {
auto* u32 = create<U32>();
auto* a = create<AccessControl>(AccessControl::kReadWrite, u32);
EXPECT_TRUE(a->IsReadWrite());
EXPECT_EQ(a->type(), u32);
}
TEST_F(AstAccessControlTest, AccessRead) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kRead, i32);
EXPECT_TRUE(ac->IsReadOnly());
EXPECT_FALSE(ac->IsWriteOnly());
EXPECT_FALSE(ac->IsReadWrite());
EXPECT_EQ(ac->type_name(), "__access_control_read_only__i32");
}
TEST_F(AstAccessControlTest, AccessWrite) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kWrite, i32);
EXPECT_FALSE(ac->IsReadOnly());
EXPECT_TRUE(ac->IsWriteOnly());
EXPECT_FALSE(ac->IsReadWrite());
EXPECT_EQ(ac->type_name(), "__access_control_write_only__i32");
}
TEST_F(AstAccessControlTest, AccessReadWrite) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kReadWrite, i32);
EXPECT_FALSE(ac->IsReadOnly());
EXPECT_FALSE(ac->IsWriteOnly());
EXPECT_TRUE(ac->IsReadWrite());
EXPECT_EQ(ac->type_name(), "__access_control_read_write__i32");
}
TEST_F(AstAccessControlTest, FriendlyNameReadOnly) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kRead, i32);
EXPECT_EQ(ac->FriendlyName(Symbols()), "[[access(read)]] i32");
}
TEST_F(AstAccessControlTest, FriendlyNameWriteOnly) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kWrite, i32);
EXPECT_EQ(ac->FriendlyName(Symbols()), "[[access(write)]] i32");
}
TEST_F(AstAccessControlTest, FriendlyNameReadWrite) {
auto* i32 = create<I32>();
auto* ac = create<AccessControl>(AccessControl::kReadWrite, i32);
EXPECT_EQ(ac->FriendlyName(Symbols()), "[[access(read_write)]] i32");
}
} // namespace
} // namespace ast
} // namespace tint

View File

@ -23,7 +23,7 @@ namespace ast {
AccessDecoration::AccessDecoration(ProgramID program_id, AccessDecoration::AccessDecoration(ProgramID program_id,
const Source& source, const Source& source,
AccessControl::Access val) Access val)
: Base(program_id, source), value_(val) {} : Base(program_id, source), value_(val) {}
AccessDecoration::~AccessDecoration() = default; AccessDecoration::~AccessDecoration() = default;

View File

@ -15,26 +15,25 @@
#ifndef SRC_AST_ACCESS_DECORATION_H_ #ifndef SRC_AST_ACCESS_DECORATION_H_
#define SRC_AST_ACCESS_DECORATION_H_ #define SRC_AST_ACCESS_DECORATION_H_
#include "src/ast/access_control.h" #include "src/ast/access.h"
#include "src/ast/decoration.h" #include "src/ast/decoration.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
/// An access decoration /// An access decoration
/// [DEPRECATED]: TODO(crbug.com/tint/846): Remove this class
class AccessDecoration : public Castable<AccessDecoration, Decoration> { class AccessDecoration : public Castable<AccessDecoration, Decoration> {
public: public:
/// constructor /// constructor
/// @param program_id the identifier of the program that owns this node /// @param program_id the identifier of the program that owns this node
/// @param source the source of this decoration /// @param source the source of this decoration
/// @param value the access value /// @param value the access value
AccessDecoration(ProgramID program_id, AccessDecoration(ProgramID program_id, const Source& source, Access value);
const Source& source,
AccessControl::Access value);
~AccessDecoration() override; ~AccessDecoration() override;
/// @returns the access control value /// @returns the access control value
AccessControl::Access value() const { return value_; } Access value() const { return value_; }
/// Outputs the decoration to the given stream /// Outputs the decoration to the given stream
/// @param sem the semantic info for the program /// @param sem the semantic info for the program
@ -51,7 +50,7 @@ class AccessDecoration : public Castable<AccessDecoration, Decoration> {
AccessDecoration* Clone(CloneContext* ctx) const override; AccessDecoration* Clone(CloneContext* ctx) const override;
private: private:
AccessControl::Access const value_; Access const value_;
}; };
} // namespace ast } // namespace ast

View File

@ -23,13 +23,13 @@ namespace {
using AccessDecorationTest = TestHelper; using AccessDecorationTest = TestHelper;
TEST_F(AccessDecorationTest, Creation) { TEST_F(AccessDecorationTest, Creation) {
auto* d = create<AccessDecoration>(ast::AccessControl::kWrite); auto* d = create<AccessDecoration>(ast::Access::kWrite);
EXPECT_EQ(ast::AccessControl::kWrite, d->value()); EXPECT_EQ(ast::Access::kWrite, d->value());
} }
TEST_F(AccessDecorationTest, ToStr) { TEST_F(AccessDecorationTest, ToStr) {
auto* d = create<AccessDecoration>(ast::AccessControl::kRead); auto* d = create<AccessDecoration>(ast::Access::kRead);
EXPECT_EQ(str(d), R"(AccessDecoration{read_only} EXPECT_EQ(str(d), R"(AccessDecoration{read}
)"); )");
} }

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
#include "src/ast/alias.h" #include "src/ast/alias.h"
#include "src/ast/access_control.h" #include "src/ast/access.h"
#include "src/ast/array.h" #include "src/ast/array.h"
#include "src/ast/bool.h" #include "src/ast/bool.h"
#include "src/ast/f32.h" #include "src/ast/f32.h"
@ -76,23 +76,6 @@ TEST_F(AstAliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) {
EXPECT_EQ(aapaa->UnwrapAll(), u32); EXPECT_EQ(aapaa->UnwrapAll(), u32);
} }
TEST_F(AstAliasTest, UnwrapAll_AccessControlPointer) {
auto* u32 = create<U32>();
auto* a = create<AccessControl>(AccessControl::kRead, u32);
auto* pa = create<Pointer>(a, StorageClass::kUniform);
EXPECT_EQ(pa->type(), a);
EXPECT_EQ(pa->UnwrapAll(), u32);
}
TEST_F(AstAliasTest, UnwrapAll_PointerAccessControl) {
auto* u32 = create<U32>();
auto* p = create<Pointer>(u32, StorageClass::kUniform);
auto* a = create<AccessControl>(AccessControl::kRead, p);
EXPECT_EQ(a->type(), p);
EXPECT_EQ(a->UnwrapAll(), u32);
}
} // namespace } // namespace
} // namespace ast } // namespace ast
} // namespace tint } // namespace tint

View File

@ -13,19 +13,8 @@
// limitations under the License. // limitations under the License.
#include "src/ast/array.h" #include "src/ast/array.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -14,7 +14,6 @@
#include "src/ast/type.h" #include "src/ast/type.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h" #include "src/ast/alias.h"
#include "src/ast/bool.h" #include "src/ast/bool.h"
#include "src/ast/f32.h" #include "src/ast/f32.h"
@ -43,8 +42,6 @@ Type* Type::UnwrapAll() {
while (true) { while (true) {
if (auto* alias = type->As<Alias>()) { if (auto* alias = type->As<Alias>()) {
type = alias->type(); type = alias->type();
} else if (auto* access = type->As<AccessControl>()) {
type = access->type();
} else if (auto* ptr = type->As<Pointer>()) { } else if (auto* ptr = type->As<Pointer>()) {
type = ptr->type(); type = ptr->type();
} else { } else {

View File

@ -13,19 +13,8 @@
// limitations under the License. // limitations under the License.
#include "src/ast/bool.h" #include "src/ast/bool.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -13,22 +13,8 @@
// limitations under the License. // limitations under the License.
#include "src/ast/depth_texture.h" #include "src/ast/depth_texture.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampled_texture.h"
#include "src/ast/sampler.h"
#include "src/ast/storage_texture.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -14,22 +14,7 @@
#include "src/ast/external_texture.h" #include "src/ast/external_texture.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/depth_texture.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/storage_texture.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -13,19 +13,8 @@
// limitations under the License. // limitations under the License.
#include "src/ast/f32.h" #include "src/ast/f32.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -189,6 +189,7 @@ TEST_F(FunctionTest, ToStr_WithParams) {
VariableConst{ VariableConst{
var var
none none
undefined
__i32 __i32
} }
) )

View File

@ -14,19 +14,7 @@
#include "src/ast/i32.h" #include "src/ast/i32.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -62,7 +62,7 @@ TextureOverloadCase::TextureOverloadCase(
TextureOverloadCase::TextureOverloadCase( TextureOverloadCase::TextureOverloadCase(
ValidTextureOverload o, ValidTextureOverload o,
const char* d, const char* d,
AccessControl::Access access, Access acc,
ast::ImageFormat i, ast::ImageFormat i,
ast::TextureDimension dims, ast::TextureDimension dims,
TextureDataType datatype, TextureDataType datatype,
@ -71,7 +71,7 @@ TextureOverloadCase::TextureOverloadCase(
: overload(o), : overload(o),
description(d), description(d),
texture_kind(TextureKind::kStorage), texture_kind(TextureKind::kStorage),
access_control(access), access(acc),
image_format(i), image_format(i),
texture_dimension(dims), texture_dimension(dims),
texture_data_type(datatype), texture_data_type(datatype),
@ -124,7 +124,7 @@ std::ostream& operator<<(std::ostream& out, const TextureOverloadCase& data) {
out << "<unused>"; out << "<unused>";
} }
out << "\n"; out << "\n";
out << "access_control: " << data.access_control << "\n"; out << "access: " << data.access << "\n";
out << "image_format: " << data.image_format << "\n"; out << "image_format: " << data.image_format << "\n";
out << "texture_dimension: " << data.texture_dimension << "\n"; out << "texture_dimension: " << data.texture_dimension << "\n";
out << "texture_data_type: " << data.texture_data_type << "\n"; out << "texture_data_type: " << data.texture_data_type << "\n";
@ -157,23 +157,22 @@ ast::Variable* TextureOverloadCase::buildTextureVariable(
return b->Global("texture", return b->Global("texture",
b->ty.sampled_texture(texture_dimension, b->ty.sampled_texture(texture_dimension,
buildResultVectorComponentType(b)), buildResultVectorComponentType(b)),
ast::StorageClass::kNone, nullptr, decos); decos);
case ast::intrinsic::test::TextureKind::kDepth: case ast::intrinsic::test::TextureKind::kDepth:
return b->Global("texture", b->ty.depth_texture(texture_dimension), return b->Global("texture", b->ty.depth_texture(texture_dimension),
ast::StorageClass::kNone, nullptr, decos); decos);
case ast::intrinsic::test::TextureKind::kMultisampled: case ast::intrinsic::test::TextureKind::kMultisampled:
return b->Global( return b->Global(
"texture", "texture",
b->ty.multisampled_texture(texture_dimension, b->ty.multisampled_texture(texture_dimension,
buildResultVectorComponentType(b)), buildResultVectorComponentType(b)),
ast::StorageClass::kNone, nullptr, decos); decos);
case ast::intrinsic::test::TextureKind::kStorage: { case ast::intrinsic::test::TextureKind::kStorage: {
auto* st = b->ty.storage_texture(texture_dimension, image_format); auto* st = b->ty.storage_texture(texture_dimension, image_format, access);
auto* ac = b->ty.access(access_control, st); return b->Global("texture", st, decos);
return b->Global("texture", ac, ast::StorageClass::kNone, nullptr, decos);
} }
} }
@ -187,8 +186,7 @@ ast::Variable* TextureOverloadCase::buildSamplerVariable(
b->create<ast::GroupDecoration>(0), b->create<ast::GroupDecoration>(0),
b->create<ast::BindingDecoration>(1), b->create<ast::BindingDecoration>(1),
}; };
return b->Global("sampler", b->ty.sampler(sampler_kind), return b->Global("sampler", b->ty.sampler(sampler_kind), decos);
ast::StorageClass::kNone, nullptr, decos);
} }
std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() { std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
@ -405,7 +403,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
{ {
ValidTextureOverload::kDimensionsStorageRO1d, ValidTextureOverload::kDimensionsStorageRO1d,
"textureDimensions(t : texture_storage_1d<rgba32float>) -> i32", "textureDimensions(t : texture_storage_1d<rgba32float>) -> i32",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k1d, ast::TextureDimension::k1d,
TextureDataType::kF32, TextureDataType::kF32,
@ -416,7 +414,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kDimensionsStorageRO2d, ValidTextureOverload::kDimensionsStorageRO2d,
"textureDimensions(t : texture_storage_2d<rgba32float>) -> " "textureDimensions(t : texture_storage_2d<rgba32float>) -> "
"vec2<i32>", "vec2<i32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kF32, TextureDataType::kF32,
@ -427,7 +425,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kDimensionsStorageRO2dArray, ValidTextureOverload::kDimensionsStorageRO2dArray,
"textureDimensions(t : texture_storage_2d_array<rgba32float>) -> " "textureDimensions(t : texture_storage_2d_array<rgba32float>) -> "
"vec2<i32>", "vec2<i32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k2dArray, ast::TextureDimension::k2dArray,
TextureDataType::kF32, TextureDataType::kF32,
@ -438,7 +436,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kDimensionsStorageRO3d, ValidTextureOverload::kDimensionsStorageRO3d,
"textureDimensions(t : texture_storage_3d<rgba32float>) -> " "textureDimensions(t : texture_storage_3d<rgba32float>) -> "
"vec3<i32>", "vec3<i32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k3d, ast::TextureDimension::k3d,
TextureDataType::kF32, TextureDataType::kF32,
@ -448,7 +446,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
{ {
ValidTextureOverload::kDimensionsStorageWO1d, ValidTextureOverload::kDimensionsStorageWO1d,
"textureDimensions(t : texture_storage_1d<rgba32float>) -> i32", "textureDimensions(t : texture_storage_1d<rgba32float>) -> i32",
ast::AccessControl::kWrite, ast::Access::kWrite,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k1d, ast::TextureDimension::k1d,
TextureDataType::kF32, TextureDataType::kF32,
@ -459,7 +457,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kDimensionsStorageWO2d, ValidTextureOverload::kDimensionsStorageWO2d,
"textureDimensions(t : texture_storage_2d<rgba32float>) -> " "textureDimensions(t : texture_storage_2d<rgba32float>) -> "
"vec2<i32>", "vec2<i32>",
ast::AccessControl::kWrite, ast::Access::kWrite,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kF32, TextureDataType::kF32,
@ -470,7 +468,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kDimensionsStorageWO2dArray, ValidTextureOverload::kDimensionsStorageWO2dArray,
"textureDimensions(t : texture_storage_2d_array<rgba32float>) -> " "textureDimensions(t : texture_storage_2d_array<rgba32float>) -> "
"vec2<i32>", "vec2<i32>",
ast::AccessControl::kWrite, ast::Access::kWrite,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k2dArray, ast::TextureDimension::k2dArray,
TextureDataType::kF32, TextureDataType::kF32,
@ -481,7 +479,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kDimensionsStorageWO3d, ValidTextureOverload::kDimensionsStorageWO3d,
"textureDimensions(t : texture_storage_3d<rgba32float>) -> " "textureDimensions(t : texture_storage_3d<rgba32float>) -> "
"vec3<i32>", "vec3<i32>",
ast::AccessControl::kWrite, ast::Access::kWrite,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k3d, ast::TextureDimension::k3d,
TextureDataType::kF32, TextureDataType::kF32,
@ -531,7 +529,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
{ {
ValidTextureOverload::kNumLayersStorageWO2dArray, ValidTextureOverload::kNumLayersStorageWO2dArray,
"textureNumLayers(t : texture_storage_2d_array<rgba32float>) -> i32", "textureNumLayers(t : texture_storage_2d_array<rgba32float>) -> i32",
ast::AccessControl::kWrite, ast::Access::kWrite,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k2dArray, ast::TextureDimension::k2dArray,
TextureDataType::kF32, TextureDataType::kF32,
@ -1887,7 +1885,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO1dRgba32float, ValidTextureOverload::kLoadStorageRO1dRgba32float,
"textureLoad(t : texture_storage_1d<rgba32float>,\n" "textureLoad(t : texture_storage_1d<rgba32float>,\n"
" coords : i32) -> vec4<f32>", " coords : i32) -> vec4<f32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k1d, ast::TextureDimension::k1d,
TextureDataType::kF32, TextureDataType::kF32,
@ -1901,7 +1899,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRgba8unorm, ValidTextureOverload::kLoadStorageRO2dRgba8unorm,
"textureLoad(t : texture_storage_2d<rgba8unorm>,\n" "textureLoad(t : texture_storage_2d<rgba8unorm>,\n"
" coords : vec2<i32>) -> vec4<f32>", " coords : vec2<i32>) -> vec4<f32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba8Unorm, ast::ImageFormat::kRgba8Unorm,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kF32, TextureDataType::kF32,
@ -1915,7 +1913,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRgba8snorm, ValidTextureOverload::kLoadStorageRO2dRgba8snorm,
"textureLoad(t : texture_storage_2d<rgba8snorm>,\n" "textureLoad(t : texture_storage_2d<rgba8snorm>,\n"
" coords : vec2<i32>) -> vec4<f32>", " coords : vec2<i32>) -> vec4<f32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba8Snorm, ast::ImageFormat::kRgba8Snorm,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kF32, TextureDataType::kF32,
@ -1929,7 +1927,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRgba8uint, ValidTextureOverload::kLoadStorageRO2dRgba8uint,
"textureLoad(t : texture_storage_2d<rgba8uint>,\n" "textureLoad(t : texture_storage_2d<rgba8uint>,\n"
" coords : vec2<i32>) -> vec4<u32>", " coords : vec2<i32>) -> vec4<u32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba8Uint, ast::ImageFormat::kRgba8Uint,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kU32, TextureDataType::kU32,
@ -1943,7 +1941,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRgba8sint, ValidTextureOverload::kLoadStorageRO2dRgba8sint,
"textureLoad(t : texture_storage_2d<rgba8sint>,\n" "textureLoad(t : texture_storage_2d<rgba8sint>,\n"
" coords : vec2<i32>) -> vec4<i32>", " coords : vec2<i32>) -> vec4<i32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba8Sint, ast::ImageFormat::kRgba8Sint,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kI32, TextureDataType::kI32,
@ -1957,7 +1955,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRgba16uint, ValidTextureOverload::kLoadStorageRO2dRgba16uint,
"textureLoad(t : texture_storage_2d<rgba16uint>,\n" "textureLoad(t : texture_storage_2d<rgba16uint>,\n"
" coords : vec2<i32>) -> vec4<u32>", " coords : vec2<i32>) -> vec4<u32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba16Uint, ast::ImageFormat::kRgba16Uint,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kU32, TextureDataType::kU32,
@ -1971,7 +1969,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRgba16sint, ValidTextureOverload::kLoadStorageRO2dRgba16sint,
"textureLoad(t : texture_storage_2d<rgba16sint>,\n" "textureLoad(t : texture_storage_2d<rgba16sint>,\n"
" coords : vec2<i32>) -> vec4<i32>", " coords : vec2<i32>) -> vec4<i32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba16Sint, ast::ImageFormat::kRgba16Sint,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kI32, TextureDataType::kI32,
@ -1985,7 +1983,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRgba16float, ValidTextureOverload::kLoadStorageRO2dRgba16float,
"textureLoad(t : texture_storage_2d<rgba16float>,\n" "textureLoad(t : texture_storage_2d<rgba16float>,\n"
" coords : vec2<i32>) -> vec4<f32>", " coords : vec2<i32>) -> vec4<f32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba16Float, ast::ImageFormat::kRgba16Float,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kF32, TextureDataType::kF32,
@ -1999,7 +1997,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dR32uint, ValidTextureOverload::kLoadStorageRO2dR32uint,
"textureLoad(t : texture_storage_2d<r32uint>,\n" "textureLoad(t : texture_storage_2d<r32uint>,\n"
" coords : vec2<i32>) -> vec4<u32>", " coords : vec2<i32>) -> vec4<u32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kR32Uint, ast::ImageFormat::kR32Uint,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kU32, TextureDataType::kU32,
@ -2013,7 +2011,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dR32sint, ValidTextureOverload::kLoadStorageRO2dR32sint,
"textureLoad(t : texture_storage_2d<r32sint>,\n" "textureLoad(t : texture_storage_2d<r32sint>,\n"
" coords : vec2<i32>) -> vec4<i32>", " coords : vec2<i32>) -> vec4<i32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kR32Sint, ast::ImageFormat::kR32Sint,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kI32, TextureDataType::kI32,
@ -2027,7 +2025,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dR32float, ValidTextureOverload::kLoadStorageRO2dR32float,
"textureLoad(t : texture_storage_2d<r32float>,\n" "textureLoad(t : texture_storage_2d<r32float>,\n"
" coords : vec2<i32>) -> vec4<f32>", " coords : vec2<i32>) -> vec4<f32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kR32Float, ast::ImageFormat::kR32Float,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kF32, TextureDataType::kF32,
@ -2041,7 +2039,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRg32uint, ValidTextureOverload::kLoadStorageRO2dRg32uint,
"textureLoad(t : texture_storage_2d<rg32uint>,\n" "textureLoad(t : texture_storage_2d<rg32uint>,\n"
" coords : vec2<i32>) -> vec4<u32>", " coords : vec2<i32>) -> vec4<u32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRg32Uint, ast::ImageFormat::kRg32Uint,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kU32, TextureDataType::kU32,
@ -2055,7 +2053,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRg32sint, ValidTextureOverload::kLoadStorageRO2dRg32sint,
"textureLoad(t : texture_storage_2d<rg32sint>,\n" "textureLoad(t : texture_storage_2d<rg32sint>,\n"
" coords : vec2<i32>) -> vec4<i32>", " coords : vec2<i32>) -> vec4<i32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRg32Sint, ast::ImageFormat::kRg32Sint,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kI32, TextureDataType::kI32,
@ -2069,7 +2067,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRg32float, ValidTextureOverload::kLoadStorageRO2dRg32float,
"textureLoad(t : texture_storage_2d<rg32float>,\n" "textureLoad(t : texture_storage_2d<rg32float>,\n"
" coords : vec2<i32>) -> vec4<f32>", " coords : vec2<i32>) -> vec4<f32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRg32Float, ast::ImageFormat::kRg32Float,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kF32, TextureDataType::kF32,
@ -2083,7 +2081,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRgba32uint, ValidTextureOverload::kLoadStorageRO2dRgba32uint,
"textureLoad(t : texture_storage_2d<rgba32uint>,\n" "textureLoad(t : texture_storage_2d<rgba32uint>,\n"
" coords : vec2<i32>) -> vec4<u32>", " coords : vec2<i32>) -> vec4<u32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba32Uint, ast::ImageFormat::kRgba32Uint,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kU32, TextureDataType::kU32,
@ -2097,7 +2095,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRgba32sint, ValidTextureOverload::kLoadStorageRO2dRgba32sint,
"textureLoad(t : texture_storage_2d<rgba32sint>,\n" "textureLoad(t : texture_storage_2d<rgba32sint>,\n"
" coords : vec2<i32>) -> vec4<i32>", " coords : vec2<i32>) -> vec4<i32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba32Sint, ast::ImageFormat::kRgba32Sint,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kI32, TextureDataType::kI32,
@ -2111,7 +2109,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO2dRgba32float, ValidTextureOverload::kLoadStorageRO2dRgba32float,
"textureLoad(t : texture_storage_2d<rgba32float>,\n" "textureLoad(t : texture_storage_2d<rgba32float>,\n"
" coords : vec2<i32>) -> vec4<f32>", " coords : vec2<i32>) -> vec4<f32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kF32, TextureDataType::kF32,
@ -2127,7 +2125,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
"texture_storage_2d_array<rgba32float>,\n" "texture_storage_2d_array<rgba32float>,\n"
" coords : vec2<i32>,\n" " coords : vec2<i32>,\n"
" array_index : i32) -> vec4<f32>", " array_index : i32) -> vec4<f32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k2dArray, ast::TextureDimension::k2dArray,
TextureDataType::kF32, TextureDataType::kF32,
@ -2142,7 +2140,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
ValidTextureOverload::kLoadStorageRO3dRgba32float, ValidTextureOverload::kLoadStorageRO3dRgba32float,
"textureLoad(t : texture_storage_3d<rgba32float>,\n" "textureLoad(t : texture_storage_3d<rgba32float>,\n"
" coords : vec3<i32>) -> vec4<f32>", " coords : vec3<i32>) -> vec4<f32>",
ast::AccessControl::kRead, ast::Access::kRead,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k3d, ast::TextureDimension::k3d,
TextureDataType::kF32, TextureDataType::kF32,
@ -2157,7 +2155,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
"textureStore(t : texture_storage_1d<rgba32float>,\n" "textureStore(t : texture_storage_1d<rgba32float>,\n"
" coords : i32,\n" " coords : i32,\n"
" value : vec4<T>)", " value : vec4<T>)",
ast::AccessControl::kWrite, ast::Access::kWrite,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k1d, ast::TextureDimension::k1d,
TextureDataType::kF32, TextureDataType::kF32,
@ -2173,7 +2171,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
"textureStore(t : texture_storage_2d<rgba32float>,\n" "textureStore(t : texture_storage_2d<rgba32float>,\n"
" coords : vec2<i32>,\n" " coords : vec2<i32>,\n"
" value : vec4<T>)", " value : vec4<T>)",
ast::AccessControl::kWrite, ast::Access::kWrite,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k2d, ast::TextureDimension::k2d,
TextureDataType::kF32, TextureDataType::kF32,
@ -2190,7 +2188,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
" coords : vec2<i32>,\n" " coords : vec2<i32>,\n"
" array_index : i32,\n" " array_index : i32,\n"
" value : vec4<T>)", " value : vec4<T>)",
ast::AccessControl::kWrite, ast::Access::kWrite,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k2dArray, ast::TextureDimension::k2dArray,
TextureDataType::kF32, TextureDataType::kF32,
@ -2207,7 +2205,7 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
"textureStore(t : texture_storage_3d<rgba32float>,\n" "textureStore(t : texture_storage_3d<rgba32float>,\n"
" coords : vec3<i32>,\n" " coords : vec3<i32>,\n"
" value : vec4<T>)", " value : vec4<T>)",
ast::AccessControl::kWrite, ast::Access::kWrite,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::TextureDimension::k3d, ast::TextureDimension::k3d,
TextureDataType::kF32, TextureDataType::kF32,

View File

@ -17,7 +17,7 @@
#include <vector> #include <vector>
#include "src/ast/access_control.h" #include "src/ast/access.h"
#include "src/program_builder.h" #include "src/program_builder.h"
#include "src/sem/storage_texture_type.h" #include "src/sem/storage_texture_type.h"
@ -192,7 +192,7 @@ struct TextureOverloadCase {
/// Constructor for textureLoad() with storage textures /// Constructor for textureLoad() with storage textures
TextureOverloadCase(ValidTextureOverload, TextureOverloadCase(ValidTextureOverload,
const char*, const char*,
AccessControl::Access, Access,
ast::ImageFormat, ast::ImageFormat,
ast::TextureDimension, ast::TextureDimension,
TextureDataType, TextureDataType,
@ -230,7 +230,7 @@ struct TextureOverloadCase {
ast::SamplerKind const sampler_kind = ast::SamplerKind::kSampler; ast::SamplerKind const sampler_kind = ast::SamplerKind::kSampler;
/// The access control for the storage texture /// The access control for the storage texture
/// Used only when texture_kind is kStorage /// Used only when texture_kind is kStorage
AccessControl::Access const access_control = AccessControl::kReadWrite; Access const access = Access::kReadWrite;
/// The image format for the storage texture /// The image format for the storage texture
/// Used only when texture_kind is kStorage /// Used only when texture_kind is kStorage
ast::ImageFormat const image_format = ast::ImageFormat::kNone; ast::ImageFormat const image_format = ast::ImageFormat::kNone;

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
#include "src/ast/matrix.h" #include "src/ast/matrix.h"
#include "src/ast/access_control.h" #include "src/ast/access.h"
#include "src/ast/alias.h" #include "src/ast/alias.h"
#include "src/ast/array.h" #include "src/ast/array.h"
#include "src/ast/bool.h" #include "src/ast/bool.h"

View File

@ -42,15 +42,15 @@ type t1 = array<vec4<f32>>;
var<private> g0 : u32 = 20u; var<private> g0 : u32 = 20u;
var<private> g1 : f32 = 123.0; var<private> g1 : f32 = 123.0;
[[group(0), binding(0)]] var g2 : texture_2d<f32>; [[group(0), binding(0)]] var g2 : texture_2d<f32>;
[[group(1), binding(0)]] var g3 : [[access(read)]] texture_storage_2d<r32uint>; [[group(1), binding(0)]] var g3 : texture_storage_2d<r32uint, read>;
[[group(2), binding(0)]] var g4 : [[access(write)]] texture_storage_2d<rg32float>; [[group(2), binding(0)]] var g4 : texture_storage_2d<rg32float, write>;
[[group(3), binding(0)]] var g5 : [[access(read)]] texture_storage_2d<r32uint>; [[group(3), binding(0)]] var g5 : texture_storage_2d<r32uint, read>;
[[group(4), binding(0)]] var g6 : [[access(write)]] texture_storage_2d<rg32float>; [[group(4), binding(0)]] var g6 : texture_storage_2d<rg32float, write>;
var<private> g7 : vec3<f32>; var<private> g7 : vec3<f32>;
[[group(0), binding(1)]] var<storage> g8 : [[access(write)]] S; [[group(0), binding(1)]] var<storage, write> g8 : S;
[[group(1), binding(1)]] var<storage> g9 : [[access(read)]] S; [[group(1), binding(1)]] var<storage, read> g9 : S;
[[group(2), binding(1)]] var<storage> g10 : [[access(read_write)]] S; [[group(2), binding(1)]] var<storage, read_write> g10 : S;
fn f0(p0 : bool) -> f32 { fn f0(p0 : bool) -> f32 {
if (p0) { if (p0) {

View File

@ -14,7 +14,7 @@
#include "src/ast/multisampled_texture.h" #include "src/ast/multisampled_texture.h"
#include "src/ast/access_control.h" #include "src/ast/access.h"
#include "src/ast/alias.h" #include "src/ast/alias.h"
#include "src/ast/array.h" #include "src/ast/array.h"
#include "src/ast/bool.h" #include "src/ast/bool.h"

View File

@ -13,19 +13,9 @@
// limitations under the License. // limitations under the License.
#include "src/ast/pointer.h" #include "src/ast/pointer.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h" #include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -14,22 +14,8 @@
#include "src/ast/sampled_texture.h" #include "src/ast/sampled_texture.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/depth_texture.h"
#include "src/ast/f32.h" #include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/storage_texture.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -13,19 +13,8 @@
// limitations under the License. // limitations under the License.
#include "src/ast/sampler.h" #include "src/ast/sampler.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -144,8 +144,12 @@ StorageTexture::StorageTexture(ProgramID program_id,
const Source& source, const Source& source,
TextureDimension dim, TextureDimension dim,
ImageFormat format, ImageFormat format,
Type* subtype) Type* subtype,
: Base(program_id, source, dim), image_format_(format), subtype_(subtype) {} Access access)
: Base(program_id, source, dim),
image_format_(format),
subtype_(subtype),
access_(access) {}
StorageTexture::StorageTexture(StorageTexture&&) = default; StorageTexture::StorageTexture(StorageTexture&&) = default;
@ -153,13 +157,15 @@ StorageTexture::~StorageTexture() = default;
std::string StorageTexture::type_name() const { std::string StorageTexture::type_name() const {
std::ostringstream out; std::ostringstream out;
out << "__storage_texture_" << dim() << "_" << image_format_; out << "__storage_texture_" << dim() << "_" << image_format_ << "_"
<< access_;
return out.str(); return out.str();
} }
std::string StorageTexture::FriendlyName(const SymbolTable&) const { std::string StorageTexture::FriendlyName(const SymbolTable&) const {
std::ostringstream out; std::ostringstream out;
out << "texture_storage_" << dim() << "<" << image_format_ << ">"; out << "texture_storage_" << dim() << "<" << image_format_ << ", " << access_
<< ">";
return out.str(); return out.str();
} }
@ -167,7 +173,8 @@ StorageTexture* StorageTexture::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source()); auto src = ctx->Clone(source());
auto* ty = ctx->Clone(type()); auto* ty = ctx->Clone(type());
return ctx->dst->create<StorageTexture>(src, dim(), image_format_, ty); return ctx->dst->create<StorageTexture>(src, dim(), image_format(), ty,
access());
} }
Type* StorageTexture::SubtypeFor(ImageFormat format, ProgramBuilder& builder) { Type* StorageTexture::SubtypeFor(ImageFormat format, ProgramBuilder& builder) {

View File

@ -17,6 +17,7 @@
#include <string> #include <string>
#include "src/ast/access.h"
#include "src/ast/texture.h" #include "src/ast/texture.h"
namespace tint { namespace tint {
@ -78,21 +79,33 @@ class StorageTexture : public Castable<StorageTexture, Texture> {
/// @param dim the dimensionality of the texture /// @param dim the dimensionality of the texture
/// @param format the image format of the texture /// @param format the image format of the texture
/// @param subtype the storage subtype. Use SubtypeFor() to calculate this. /// @param subtype the storage subtype. Use SubtypeFor() to calculate this.
/// @param access_control the access control for the texture.
StorageTexture(ProgramID program_id, StorageTexture(ProgramID program_id,
const Source& source, const Source& source,
TextureDimension dim, TextureDimension dim,
ImageFormat format, ImageFormat format,
Type* subtype); Type* subtype,
Access access_control);
/// Move constructor /// Move constructor
StorageTexture(StorageTexture&&); StorageTexture(StorageTexture&&);
~StorageTexture() override; ~StorageTexture() override;
/// @returns the image format
ImageFormat image_format() const { return image_format_; }
/// @returns the storage subtype /// @returns the storage subtype
Type* type() const { return subtype_; } Type* type() const { return subtype_; }
/// @returns the image format /// @returns the access control
ImageFormat image_format() const { return image_format_; } Access access() const { return access_; }
/// @returns true if the access control is read only
bool is_read_only() const { return access_ == Access::kRead; }
/// @returns true if the access control is write only
bool is_write_only() const { return access_ == Access::kWrite; }
/// @returns true if the access control is read/write
bool is_read_write() const { return access_ == Access::kReadWrite; }
/// @returns the name for this type /// @returns the name for this type
std::string type_name() const override; std::string type_name() const override;
@ -115,6 +128,7 @@ class StorageTexture : public Castable<StorageTexture, Texture> {
private: private:
ImageFormat const image_format_; ImageFormat const image_format_;
Type* const subtype_; Type* const subtype_;
Access const access_;
}; };
} // namespace ast } // namespace ast

View File

@ -13,22 +13,8 @@
// limitations under the License. // limitations under the License.
#include "src/ast/storage_texture.h" #include "src/ast/storage_texture.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/depth_texture.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampled_texture.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -38,8 +24,9 @@ using AstStorageTextureTest = TestHelper;
TEST_F(AstStorageTextureTest, IsTexture) { TEST_F(AstStorageTextureTest, IsTexture) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this); auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
Texture* ty = create<StorageTexture>(TextureDimension::k2dArray, Texture* ty =
ImageFormat::kRgba32Float, subtype); create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype, Access::kRead);
EXPECT_FALSE(ty->Is<DepthTexture>()); EXPECT_FALSE(ty->Is<DepthTexture>());
EXPECT_FALSE(ty->Is<SampledTexture>()); EXPECT_FALSE(ty->Is<SampledTexture>());
EXPECT_TRUE(ty->Is<StorageTexture>()); EXPECT_TRUE(ty->Is<StorageTexture>());
@ -47,37 +34,42 @@ TEST_F(AstStorageTextureTest, IsTexture) {
TEST_F(AstStorageTextureTest, Dim) { TEST_F(AstStorageTextureTest, Dim) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this); auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
auto* s = create<StorageTexture>(TextureDimension::k2dArray, auto* s =
ImageFormat::kRgba32Float, subtype); create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype, Access::kRead);
EXPECT_EQ(s->dim(), TextureDimension::k2dArray); EXPECT_EQ(s->dim(), TextureDimension::k2dArray);
} }
TEST_F(AstStorageTextureTest, Format) { TEST_F(AstStorageTextureTest, Format) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this); auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
auto* s = create<StorageTexture>(TextureDimension::k2dArray, auto* s =
ImageFormat::kRgba32Float, subtype); create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype, Access::kRead);
EXPECT_EQ(s->image_format(), ImageFormat::kRgba32Float); EXPECT_EQ(s->image_format(), ImageFormat::kRgba32Float);
} }
TEST_F(AstStorageTextureTest, TypeName) { TEST_F(AstStorageTextureTest, TypeName) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this); auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
auto* s = create<StorageTexture>(TextureDimension::k2dArray, auto* s =
ImageFormat::kRgba32Float, subtype); create<StorageTexture>(TextureDimension::k2dArray,
EXPECT_EQ(s->type_name(), "__storage_texture_2d_array_rgba32float"); ImageFormat::kRgba32Float, subtype, Access::kRead);
EXPECT_EQ(s->type_name(), "__storage_texture_2d_array_rgba32float_read");
} }
TEST_F(AstStorageTextureTest, FriendlyName) { TEST_F(AstStorageTextureTest, FriendlyName) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this); auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
auto* s = create<StorageTexture>(TextureDimension::k2dArray, auto* s =
ImageFormat::kRgba32Float, subtype); create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype, Access::kRead);
EXPECT_EQ(s->FriendlyName(Symbols()), EXPECT_EQ(s->FriendlyName(Symbols()),
"texture_storage_2d_array<rgba32float>"); "texture_storage_2d_array<rgba32float, read>");
} }
TEST_F(AstStorageTextureTest, F32) { TEST_F(AstStorageTextureTest, F32) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this); auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, *this);
Type* s = create<StorageTexture>(TextureDimension::k2dArray, Type* s =
ImageFormat::kRgba32Float, subtype); create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Float, subtype, Access::kRead);
ASSERT_TRUE(s->Is<Texture>()); ASSERT_TRUE(s->Is<Texture>());
ASSERT_TRUE(s->Is<StorageTexture>()); ASSERT_TRUE(s->Is<StorageTexture>());
@ -86,8 +78,9 @@ TEST_F(AstStorageTextureTest, F32) {
TEST_F(AstStorageTextureTest, U32) { TEST_F(AstStorageTextureTest, U32) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRg32Uint, *this); auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRg32Uint, *this);
Type* s = create<StorageTexture>(TextureDimension::k2dArray, Type* s =
ImageFormat::kRg32Uint, subtype); create<StorageTexture>(TextureDimension::k2dArray, ImageFormat::kRg32Uint,
subtype, Access::kRead);
ASSERT_TRUE(s->Is<Texture>()); ASSERT_TRUE(s->Is<Texture>());
ASSERT_TRUE(s->Is<StorageTexture>()); ASSERT_TRUE(s->Is<StorageTexture>());
@ -96,8 +89,9 @@ TEST_F(AstStorageTextureTest, U32) {
TEST_F(AstStorageTextureTest, I32) { TEST_F(AstStorageTextureTest, I32) {
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Sint, *this); auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Sint, *this);
Type* s = create<StorageTexture>(TextureDimension::k2dArray, Type* s =
ImageFormat::kRgba32Sint, subtype); create<StorageTexture>(TextureDimension::k2dArray,
ImageFormat::kRgba32Sint, subtype, Access::kRead);
ASSERT_TRUE(s->Is<Texture>()); ASSERT_TRUE(s->Is<Texture>());
ASSERT_TRUE(s->Is<StorageTexture>()); ASSERT_TRUE(s->Is<StorageTexture>());

View File

@ -14,19 +14,7 @@
#include "src/ast/u32.h" #include "src/ast/u32.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/vector.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -27,6 +27,7 @@ Variable::Variable(ProgramID program_id,
const Source& source, const Source& source,
const Symbol& sym, const Symbol& sym,
StorageClass declared_storage_class, StorageClass declared_storage_class,
Access declared_access,
const ast::Type* type, const ast::Type* type,
bool is_const, bool is_const,
Expression* constructor, Expression* constructor,
@ -37,7 +38,8 @@ Variable::Variable(ProgramID program_id,
is_const_(is_const), is_const_(is_const),
constructor_(constructor), constructor_(constructor),
decorations_(std::move(decorations)), decorations_(std::move(decorations)),
declared_storage_class_(declared_storage_class) { declared_storage_class_(declared_storage_class),
declared_access_(declared_access) {
TINT_ASSERT(symbol_.IsValid()); TINT_ASSERT(symbol_.IsValid());
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(symbol_, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(symbol_, program_id);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(constructor, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(constructor, program_id);
@ -66,8 +68,9 @@ Variable* Variable::Clone(CloneContext* ctx) const {
auto* ty = ctx->Clone(type()); auto* ty = ctx->Clone(type());
auto* ctor = ctx->Clone(constructor()); auto* ctor = ctx->Clone(constructor());
auto decos = ctx->Clone(decorations()); auto decos = ctx->Clone(decorations());
return ctx->dst->create<Variable>(src, sym, declared_storage_class(), ty, return ctx->dst->create<Variable>(src, sym, declared_storage_class(),
is_const_, ctor, decos); declared_access(), ty, is_const_, ctor,
decos);
} }
void Variable::info_to_str(const sem::Info& sem, void Variable::info_to_str(const sem::Info& sem,
@ -80,6 +83,8 @@ void Variable::info_to_str(const sem::Info& sem,
out << (var_sem ? var_sem->StorageClass() : declared_storage_class()) out << (var_sem ? var_sem->StorageClass() : declared_storage_class())
<< std::endl; << std::endl;
make_indent(out, indent); make_indent(out, indent);
out << declared_access_ << std::endl;
make_indent(out, indent);
out << type_->type_name() << std::endl; out << type_->type_name() << std::endl;
} }

View File

@ -18,6 +18,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "src/ast/access.h"
#include "src/ast/decoration.h" #include "src/ast/decoration.h"
#include "src/ast/expression.h" #include "src/ast/expression.h"
#include "src/ast/storage_class.h" #include "src/ast/storage_class.h"
@ -103,6 +104,7 @@ class Variable : public Castable<Variable, Node> {
/// @param source the variable source /// @param source the variable source
/// @param sym the variable symbol /// @param sym the variable symbol
/// @param declared_storage_class the declared storage class /// @param declared_storage_class the declared storage class
/// @param declared_access the declared access control
/// @param type the declared variable type /// @param type the declared variable type
/// @param is_const true if the variable is const /// @param is_const true if the variable is const
/// @param constructor the constructor expression /// @param constructor the constructor expression
@ -111,6 +113,7 @@ class Variable : public Castable<Variable, Node> {
const Source& source, const Source& source,
const Symbol& sym, const Symbol& sym,
StorageClass declared_storage_class, StorageClass declared_storage_class,
Access declared_access,
const ast::Type* type, const ast::Type* type,
bool is_const, bool is_const,
Expression* constructor, Expression* constructor,
@ -130,6 +133,10 @@ class Variable : public Castable<Variable, Node> {
StorageClass declared_storage_class() const { StorageClass declared_storage_class() const {
return declared_storage_class_; return declared_storage_class_;
} }
/// @returns the declared access control
Access declared_access() const { return declared_access_; }
/// @returns the constructor expression or nullptr if none set /// @returns the constructor expression or nullptr if none set
Expression* constructor() const { return constructor_; } Expression* constructor() const { return constructor_; }
/// @returns true if the variable has an constructor /// @returns true if the variable has an constructor
@ -184,6 +191,7 @@ class Variable : public Castable<Variable, Node> {
Expression* const constructor_; Expression* const constructor_;
DecorationList const decorations_; DecorationList const decorations_;
StorageClass const declared_storage_class_; StorageClass const declared_storage_class_;
Access const declared_access_;
}; };
/// A list of variables /// A list of variables

View File

@ -76,6 +76,7 @@ TEST_F(VariableDeclStatementTest, ToStr) {
Variable{ Variable{
a a
none none
undefined
__f32 __f32
} }
} }

View File

@ -92,10 +92,12 @@ TEST_F(VariableTest, Assert_DifferentProgramID_Constructor) {
} }
TEST_F(VariableTest, to_str) { TEST_F(VariableTest, to_str) {
auto* v = Var("my_var", ty.f32(), StorageClass::kFunction); auto* v =
Var("my_var", ty.f32(), StorageClass::kFunction, ast::Access::kReadWrite);
EXPECT_EQ(str(v), R"(Variable{ EXPECT_EQ(str(v), R"(Variable{
my_var my_var
function function
read_write
__f32 __f32
} }
)"); )");
@ -161,7 +163,8 @@ TEST_F(VariableTest, BindingPointMissingBindingDecoration) {
} }
TEST_F(VariableTest, Decorated_to_str) { TEST_F(VariableTest, Decorated_to_str) {
auto* var = Var("my_var", ty.f32(), StorageClass::kFunction, Expr("expr"), auto* var = Var("my_var", ty.f32(), StorageClass::kFunction,
ast::Access::kRead, Expr("expr"),
DecorationList{ DecorationList{
create<BindingDecoration>(2), create<BindingDecoration>(2),
create<GroupDecoration>(1), create<GroupDecoration>(1),
@ -174,6 +177,7 @@ TEST_F(VariableTest, Decorated_to_str) {
} }
my_var my_var
function function
read
__f32 __f32
{ {
Identifier[not set]{expr} Identifier[not set]{expr}

View File

@ -13,19 +13,9 @@
// limitations under the License. // limitations under the License.
#include "src/ast/vector.h" #include "src/ast/vector.h"
#include "src/ast/access_control.h"
#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/bool.h"
#include "src/ast/f32.h"
#include "src/ast/i32.h" #include "src/ast/i32.h"
#include "src/ast/matrix.h"
#include "src/ast/pointer.h"
#include "src/ast/sampler.h"
#include "src/ast/struct.h"
#include "src/ast/test_helper.h" #include "src/ast/test_helper.h"
#include "src/ast/texture.h"
#include "src/ast/u32.h"
namespace tint { namespace tint {
namespace ast { namespace ast {

View File

@ -641,7 +641,7 @@ std::vector<ResourceBinding> Inspector::GetStorageBufferResourceBindingsImpl(
auto* var = rsv.first; auto* var = rsv.first;
auto binding_info = rsv.second; auto binding_info = rsv.second;
if (read_only != (var->AccessControl() == ast::AccessControl::kRead)) { if (read_only != (var->Access() == ast::Access::kRead)) {
continue; continue;
} }
@ -723,8 +723,7 @@ std::vector<ResourceBinding> Inspector::GetStorageTextureResourceBindingsImpl(
auto* texture_type = var->Type()->UnwrapRef()->As<sem::StorageTexture>(); auto* texture_type = var->Type()->UnwrapRef()->As<sem::StorageTexture>();
if (read_only != if (read_only != (texture_type->access() == ast::Access::kRead)) {
(texture_type->access_control() == ast::AccessControl::kRead)) {
continue; continue;
} }

View File

@ -235,47 +235,12 @@ class InspectorHelper : public ProgramBuilder {
/// Generates types appropriate for using in a storage buffer /// Generates types appropriate for using in a storage buffer
/// @param name name for the type /// @param name name for the type
/// @param member_types a vector of member types /// @param member_types a vector of member types
/// @returns a function that returns an ast::AccessControl to the created /// @returns a function that returns the created structure.
/// structure. std::function<ast::TypeName*()> MakeStorageBufferTypes(
std::function<ast::AccessControl*()> MakeStorageBufferTypes(
const std::string& name, const std::string& name,
std::vector<ast::Type*> member_types) { std::vector<ast::Type*> member_types) {
MakeStructType(name, member_types, true); MakeStructType(name, member_types, true);
return [this, name] { return [this, name] { return ty.type_name(name); };
return ty.access(ast::AccessControl::kReadWrite, ty.type_name(name));
};
}
/// Generates types appropriate for using in a read-only storage buffer
/// @param name name for the type
/// @param member_types a vector of member types
/// @returns a function that returns an ast::AccessControl to the created
/// structure.
std::function<ast::AccessControl*()> MakeReadOnlyStorageBufferTypes(
const std::string& name,
std::vector<ast::Type*> member_types) {
MakeStructType(name, member_types, true);
return [this, name] {
return ty.access(ast::AccessControl::kRead, ty.type_name(name));
};
}
/// Adds a binding variable with a struct type to the program
/// @param name the name of the variable
/// @param type the type to use
/// @param storage_class the storage class to use
/// @param group the binding and group to use for the uniform buffer
/// @param binding the binding number to use for the uniform buffer
void AddBinding(const std::string& name,
ast::Type* type,
ast::StorageClass storage_class,
uint32_t group,
uint32_t binding) {
Global(name, type, storage_class, nullptr,
ast::DecorationList{
create<ast::BindingDecoration>(binding),
create<ast::GroupDecoration>(group),
});
} }
/// Adds an uniform buffer variable to the program /// Adds an uniform buffer variable to the program
@ -287,19 +252,29 @@ class InspectorHelper : public ProgramBuilder {
ast::Type* type, ast::Type* type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kUniform, group, binding); Global(name, type, ast::StorageClass::kUniform,
ast::DecorationList{
create<ast::BindingDecoration>(binding),
create<ast::GroupDecoration>(group),
});
} }
/// Adds a storage buffer variable to the program /// Adds a storage buffer variable to the program
/// @param name the name of the variable /// @param name the name of the variable
/// @param type the type to use /// @param type the type to use
/// @param access the storage buffer access control
/// @param group the binding/group to use for the storage buffer /// @param group the binding/group to use for the storage buffer
/// @param binding the binding number to use for the storage buffer /// @param binding the binding number to use for the storage buffer
void AddStorageBuffer(const std::string& name, void AddStorageBuffer(const std::string& name,
ast::Type* type, ast::Type* type,
ast::Access access,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kStorage, group, binding); Global(name, type, ast::StorageClass::kStorage, access,
ast::DecorationList{
create<ast::BindingDecoration>(binding),
create<ast::GroupDecoration>(group),
});
} }
/// Generates a function that references a specific struct variable /// Generates a function that references a specific struct variable
@ -341,7 +316,11 @@ class InspectorHelper : public ProgramBuilder {
/// @param group the binding/group to use for the storage buffer /// @param group the binding/group to use for the storage buffer
/// @param binding the binding number to use for the storage buffer /// @param binding the binding number to use for the storage buffer
void AddSampler(const std::string& name, uint32_t group, uint32_t binding) { void AddSampler(const std::string& name, uint32_t group, uint32_t binding) {
AddBinding(name, sampler_type(), ast::StorageClass::kNone, group, binding); Global(name, sampler_type(),
ast::DecorationList{
create<ast::BindingDecoration>(binding),
create<ast::GroupDecoration>(group),
});
} }
/// Adds a comparison sampler variable to the program /// Adds a comparison sampler variable to the program
@ -351,8 +330,11 @@ class InspectorHelper : public ProgramBuilder {
void AddComparisonSampler(const std::string& name, void AddComparisonSampler(const std::string& name,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, comparison_sampler_type(), ast::StorageClass::kNone, group, Global(name, comparison_sampler_type(),
binding); ast::DecorationList{
create<ast::BindingDecoration>(binding),
create<ast::GroupDecoration>(group),
});
} }
/// Generates a SampledTexture appropriate for the params /// Generates a SampledTexture appropriate for the params
@ -396,7 +378,11 @@ class InspectorHelper : public ProgramBuilder {
ast::Type* type, ast::Type* type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kNone, group, binding); Global(name, type,
ast::DecorationList{
create<ast::BindingDecoration>(binding),
create<ast::GroupDecoration>(group),
});
} }
/// Adds a multi-sampled texture variable to the program /// Adds a multi-sampled texture variable to the program
@ -408,7 +394,11 @@ class InspectorHelper : public ProgramBuilder {
ast::Type* type, ast::Type* type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kNone, group, binding); Global(name, type,
ast::DecorationList{
create<ast::BindingDecoration>(binding),
create<ast::GroupDecoration>(group),
});
} }
void AddGlobalVariable(const std::string& name, ast::Type* type) { void AddGlobalVariable(const std::string& name, ast::Type* type) {
@ -424,7 +414,11 @@ class InspectorHelper : public ProgramBuilder {
ast::Type* type, ast::Type* type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kNone, group, binding); Global(name, type,
ast::DecorationList{
create<ast::BindingDecoration>(binding),
create<ast::GroupDecoration>(group),
});
} }
/// Adds an external texture variable to the program /// Adds an external texture variable to the program
@ -436,7 +430,11 @@ class InspectorHelper : public ProgramBuilder {
ast::Type* type, ast::Type* type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kNone, group, binding); Global(name, type,
ast::DecorationList{
create<ast::BindingDecoration>(binding),
create<ast::GroupDecoration>(group),
});
} }
/// Generates a function that references a specific sampler variable /// Generates a function that references a specific sampler variable
@ -571,15 +569,12 @@ class InspectorHelper : public ProgramBuilder {
/// @param dim the texture dimension of the storage texture /// @param dim the texture dimension of the storage texture
/// @param format the image format of the storage texture /// @param format the image format of the storage texture
/// @param read_only should the access type be read only, otherwise write only /// @param read_only should the access type be read only, otherwise write only
/// @returns the storage texture type, subtype & access control type /// @returns the storage texture type
ast::Type* MakeStorageTextureTypes(ast::TextureDimension dim, ast::Type* MakeStorageTextureTypes(ast::TextureDimension dim,
ast::ImageFormat format, ast::ImageFormat format,
bool read_only) { bool read_only) {
auto ac = auto access = read_only ? ast::Access::kRead : ast::Access::kWrite;
read_only ? ast::AccessControl::kRead : ast::AccessControl::kWrite; return ty.storage_texture(dim, format, access);
auto* tex = ty.storage_texture(dim, format);
return ty.access(ac, tex);
} }
/// Adds a storage texture variable to the program /// Adds a storage texture variable to the program
@ -591,7 +586,11 @@ class InspectorHelper : public ProgramBuilder {
ast::Type* type, ast::Type* type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kNone, group, binding); Global(name, type,
ast::DecorationList{
create<ast::BindingDecoration>(binding),
create<ast::GroupDecoration>(group),
});
} }
/// Generates a function that references a storage texture variable. /// Generates a function that references a storage texture variable.
@ -1664,11 +1663,11 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) {
MakeStructVariableReferenceBodyFunction("ub_func", "ub_var", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("ub_func", "ub_var", {{0, ty.i32()}});
auto sb = MakeStorageBufferTypes("sb_type", {ty.i32()}); auto sb = MakeStorageBufferTypes("sb_type", {ty.i32()});
AddStorageBuffer("sb_var", sb(), 1, 0); AddStorageBuffer("sb_var", sb(), ast::Access::kReadWrite, 1, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "sb_var", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "sb_var", {{0, ty.i32()}});
auto ro_sb = MakeReadOnlyStorageBufferTypes("rosb_type", {ty.i32()}); auto ro_sb = MakeStorageBufferTypes("rosb_type", {ty.i32()});
AddStorageBuffer("rosb_var", ro_sb(), 1, 1); AddStorageBuffer("rosb_var", ro_sb(), ast::Access::kRead, 1, 1);
MakeStructVariableReferenceBodyFunction("rosb_func", "rosb_var", MakeStructVariableReferenceBodyFunction("rosb_func", "rosb_var",
{{0, ty.i32()}}); {{0, ty.i32()}});
@ -1949,7 +1948,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingArray) {
TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple) {
auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32()}); auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32()});
AddStorageBuffer("foo_sb", foo_struct_type(), 0, 0); AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -1978,7 +1977,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleMembers) {
ty.u32(), ty.u32(),
ty.f32(), ty.f32(),
}); });
AddStorageBuffer("foo_sb", foo_struct_type(), 0, 0); AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
MakeStructVariableReferenceBodyFunction( MakeStructVariableReferenceBodyFunction(
"sb_func", "foo_sb", {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}}); "sb_func", "foo_sb", {{0, ty.i32()}, {1, ty.u32()}, {2, ty.f32()}});
@ -2008,9 +2007,9 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
ty.u32(), ty.u32(),
ty.f32(), ty.f32(),
}); });
AddStorageBuffer("sb_foo", sb_struct_type(), 0, 0); AddStorageBuffer("sb_foo", sb_struct_type(), ast::Access::kReadWrite, 0, 0);
AddStorageBuffer("sb_bar", sb_struct_type(), 0, 1); AddStorageBuffer("sb_bar", sb_struct_type(), ast::Access::kReadWrite, 0, 1);
AddStorageBuffer("sb_baz", sb_struct_type(), 2, 0); AddStorageBuffer("sb_baz", sb_struct_type(), ast::Access::kReadWrite, 2, 0);
auto AddReferenceFunc = [this](const std::string& func_name, auto AddReferenceFunc = [this](const std::string& func_name,
const std::string& var_name) { const std::string& var_name) {
@ -2067,7 +2066,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) {
auto foo_struct_type = auto foo_struct_type =
MakeStorageBufferTypes("foo_type", {ty.i32(), ty.array<u32, 4>()}); MakeStorageBufferTypes("foo_type", {ty.i32(), ty.array<u32, 4>()});
AddStorageBuffer("foo_sb", foo_struct_type(), 0, 0); AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -2095,7 +2094,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
ty.i32(), ty.i32(),
ty.array<u32>(), ty.array<u32>(),
}); });
AddStorageBuffer("foo_sb", foo_struct_type(), 0, 0); AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -2120,7 +2119,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) {
auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.vec3<f32>()}); auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.vec3<f32>()});
AddStorageBuffer("foo_sb", foo_struct_type(), 0, 0); AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
{{0, ty.vec3<f32>()}}); {{0, ty.vec3<f32>()}});
@ -2145,8 +2144,8 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) {
} }
TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) {
auto foo_struct_type = MakeReadOnlyStorageBufferTypes("foo_type", {ty.i32()}); auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32()});
AddStorageBuffer("foo_sb", foo_struct_type(), 0, 0); AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -2163,8 +2162,8 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) {
} }
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) { TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) {
auto foo_struct_type = MakeReadOnlyStorageBufferTypes("foo_type", {ty.i32()}); auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32()});
AddStorageBuffer("foo_sb", foo_struct_type(), 0, 0); AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -2189,14 +2188,14 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) {
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
MultipleStorageBuffers) { MultipleStorageBuffers) {
auto sb_struct_type = MakeReadOnlyStorageBufferTypes("sb_type", { auto sb_struct_type = MakeStorageBufferTypes("sb_type", {
ty.i32(), ty.i32(),
ty.u32(), ty.u32(),
ty.f32(), ty.f32(),
}); });
AddStorageBuffer("sb_foo", sb_struct_type(), 0, 0); AddStorageBuffer("sb_foo", sb_struct_type(), ast::Access::kRead, 0, 0);
AddStorageBuffer("sb_bar", sb_struct_type(), 0, 1); AddStorageBuffer("sb_bar", sb_struct_type(), ast::Access::kRead, 0, 1);
AddStorageBuffer("sb_baz", sb_struct_type(), 2, 0); AddStorageBuffer("sb_baz", sb_struct_type(), ast::Access::kRead, 2, 0);
auto AddReferenceFunc = [this](const std::string& func_name, auto AddReferenceFunc = [this](const std::string& func_name,
const std::string& var_name) { const std::string& var_name) {
@ -2252,11 +2251,11 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) { TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
auto foo_struct_type = auto foo_struct_type =
MakeReadOnlyStorageBufferTypes("foo_type", { MakeStorageBufferTypes("foo_type", {
ty.i32(), ty.i32(),
ty.array<u32, 4>(), ty.array<u32, 4>(),
}); });
AddStorageBuffer("foo_sb", foo_struct_type(), 0, 0); AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -2281,12 +2280,11 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
ContainingRuntimeArray) { ContainingRuntimeArray) {
auto foo_struct_type = auto foo_struct_type = MakeStorageBufferTypes("foo_type", {
MakeReadOnlyStorageBufferTypes("foo_type", { ty.i32(),
ty.i32(), ty.array<u32>(),
ty.array<u32>(), });
}); AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
AddStorageBuffer("foo_sb", foo_struct_type(), 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -2311,7 +2309,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) { TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {
auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32()}); auto foo_struct_type = MakeStorageBufferTypes("foo_type", {ty.i32()});
AddStorageBuffer("foo_sb", foo_struct_type(), 0, 0); AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});

View File

@ -286,7 +286,7 @@ class OpenNumberMatcher : public NumberMatcher {
// template // template
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
using TexelFormat = ast::ImageFormat; using TexelFormat = ast::ImageFormat;
using AccessControl = ast::AccessControl::Access; using Access = ast::Access;
using StorageClass = ast::StorageClass; using StorageClass = ast::StorageClass;
using ParameterUsage = sem::ParameterUsage; using ParameterUsage = sem::ParameterUsage;
using PipelineStageSet = sem::PipelineStageSet; using PipelineStageSet = sem::PipelineStageSet;
@ -577,7 +577,7 @@ bool match_texture_storage(const sem::Type* ty,
if (auto* v = ty->As<sem::StorageTexture>()) { if (auto* v = ty->As<sem::StorageTexture>()) {
if (v->dim() == dim) { if (v->dim() == dim) {
F = Number(static_cast<uint32_t>(v->image_format())); F = Number(static_cast<uint32_t>(v->image_format()));
A = Number(static_cast<uint32_t>(v->access_control())); A = Number(static_cast<uint32_t>(v->access()));
return true; return true;
} }
} }
@ -592,7 +592,7 @@ bool match_texture_storage(const sem::Type* ty,
const sem::StorageTexture* JOIN(build_texture_storage_, suffix)( \ const sem::StorageTexture* JOIN(build_texture_storage_, suffix)( \
MatchState & state, Number F, Number A) { \ MatchState & state, Number F, Number A) { \
auto format = static_cast<TexelFormat>(F.Value()); \ auto format = static_cast<TexelFormat>(F.Value()); \
auto access = static_cast<AccessControl>(A.Value()); \ auto access = static_cast<Access>(A.Value()); \
auto* T = sem::StorageTexture::SubtypeFor(format, state.builder.Types()); \ auto* T = sem::StorageTexture::SubtypeFor(format, state.builder.Types()); \
return state.builder.create<sem::StorageTexture>(dim, format, access, T); \ return state.builder.create<sem::StorageTexture>(dim, format, access, T); \
} }

View File

@ -1184,9 +1184,9 @@ class ReadOrWrite : public NumberMatcher {
}; };
Number ReadOrWrite::Match(MatchState&, Number number) const { Number ReadOrWrite::Match(MatchState&, Number number) const {
switch (static_cast<AccessControl>(number.Value())) { switch (static_cast<Access>(number.Value())) {
case AccessControl::kRead: case Access::kRead:
case AccessControl::kWrite: case Access::kWrite:
return number; return number;
default: default:
return Number::invalid; return Number::invalid;
@ -1212,8 +1212,8 @@ class Write : public NumberMatcher {
}; };
Number Write::Match(MatchState&, Number number) const { Number Write::Match(MatchState&, Number number) const {
if (number.IsAny() || number.Value() == static_cast<uint32_t>(AccessControl::kWrite)) { if (number.IsAny() || number.Value() == static_cast<uint32_t>(Access::kWrite)) {
return Number(AccessControl::kWrite); return Number(Access::kWrite);
} }
return Number::invalid; return Number::invalid;
} }
@ -1237,8 +1237,8 @@ class Read : public NumberMatcher {
}; };
Number Read::Match(MatchState&, Number number) const { Number Read::Match(MatchState&, Number number) const {
if (number.IsAny() || number.Value() == static_cast<uint32_t>(AccessControl::kRead)) { if (number.IsAny() || number.Value() == static_cast<uint32_t>(Access::kRead)) {
return Number(AccessControl::kRead); return Number(Access::kRead);
} }
return Number::invalid; return Number::invalid;
} }

View File

@ -338,7 +338,7 @@ TEST_F(IntrinsicTableTest, MatchROStorageTexture) {
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()); sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types());
auto* tex = create<sem::StorageTexture>(ast::TextureDimension::k2d, auto* tex = create<sem::StorageTexture>(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Float, ast::ImageFormat::kR32Float,
ast::AccessControl::kRead, subtype); ast::Access::kRead, subtype);
auto* result = auto* result =
table->Lookup(IntrinsicType::kTextureLoad, {tex, vec2_i32}, Source{}); table->Lookup(IntrinsicType::kTextureLoad, {tex, vec2_i32}, Source{});
@ -360,7 +360,7 @@ TEST_F(IntrinsicTableTest, MatchWOStorageTexture) {
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()); sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types());
auto* tex = create<sem::StorageTexture>(ast::TextureDimension::k2d, auto* tex = create<sem::StorageTexture>(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Float, ast::ImageFormat::kR32Float,
ast::AccessControl::kWrite, subtype); ast::Access::kWrite, subtype);
auto* result = table->Lookup(IntrinsicType::kTextureStore, auto* result = table->Lookup(IntrinsicType::kTextureStore,
{tex, vec2_i32, vec4_f32}, Source{}); {tex, vec2_i32, vec4_f32}, Source{});

View File

@ -34,7 +34,7 @@ enum storage_class {
} }
// https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode // https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode
enum access_control { enum access {
read read
write write
read_write read_write
@ -89,10 +89,10 @@ type texture_depth_2d
type texture_depth_2d_array type texture_depth_2d_array
type texture_depth_cube type texture_depth_cube
type texture_depth_cube_array type texture_depth_cube_array
type texture_storage_1d<F: texel_format, A: access_control> type texture_storage_1d<F: texel_format, A: access>
type texture_storage_2d<F: texel_format, A: access_control> type texture_storage_2d<F: texel_format, A: access>
type texture_storage_2d_array<F: texel_format, A: access_control> type texture_storage_2d_array<F: texel_format, A: access>
type texture_storage_3d<F: texel_format, A: access_control> type texture_storage_3d<F: texel_format, A: access>
type texture_external type texture_external
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -245,7 +245,7 @@ match read_or_write: read | write
// - Single parameter of vector type with open-number size N and element // // - Single parameter of vector type with open-number size N and element //
// open-type T // // open-type T //
// // // //
// fn F<A: access_control>(texture_storage_1d<f32_texel_format, A>) // // fn F<A: access>(texture_storage_1d<f32_texel_format, A>) //
// - Single parameter of texture_storage_1d type with open-number // // - Single parameter of texture_storage_1d type with open-number //
// access-control C, and of a texel format that is listed in // // access-control C, and of a texel format that is listed in //
// f32_texel_format // // f32_texel_format //

View File

@ -101,11 +101,13 @@ class ProgramBuilder {
~VarOptionals(); ~VarOptionals();
ast::StorageClass storage = ast::StorageClass::kNone; ast::StorageClass storage = ast::StorageClass::kNone;
ast::Access access = ast::Access::kUndefined;
ast::Expression* constructor = nullptr; ast::Expression* constructor = nullptr;
ast::DecorationList decorations = {}; ast::DecorationList decorations = {};
private: private:
void Set(ast::StorageClass sc) { storage = sc; } void Set(ast::StorageClass sc) { storage = sc; }
void Set(ast::Access ac) { access = ac; }
void Set(ast::Expression* c) { constructor = c; } void Set(ast::Expression* c) { constructor = c; }
void Set(const ast::DecorationList& l) { decorations = l; } void Set(const ast::DecorationList& l) { decorations = l; }
@ -708,29 +710,6 @@ class ProgramBuilder {
return builder->create<ast::Alias>(source, sym, type); return builder->create<ast::Alias>(source, sym, type);
} }
/// Creates an access control qualifier type
/// @param access the access control
/// @param type the inner type
/// @returns the access control qualifier type
ast::AccessControl* access(ast::AccessControl::Access access,
const ast::Type* type) const {
type = MaybeCreateTypename(type);
return type ? builder->create<ast::AccessControl>(access, type) : nullptr;
}
/// Creates an access control qualifier type
/// @param source the Source of the node
/// @param access the access control
/// @param type the inner type
/// @returns the access control qualifier type
ast::AccessControl* access(const Source& source,
ast::AccessControl::Access access,
const ast::Type* type) const {
type = MaybeCreateTypename(type);
return type ? builder->create<ast::AccessControl>(source, access, type)
: nullptr;
}
/// @param type the type of the pointer /// @param type the type of the pointer
/// @param storage_class the storage class of the pointer /// @param storage_class the storage class of the pointer
/// @return the pointer to `type` with the given ast::StorageClass /// @return the pointer to `type` with the given ast::StorageClass
@ -823,23 +802,28 @@ class ProgramBuilder {
/// @param dims the dimensionality of the texture /// @param dims the dimensionality of the texture
/// @param format the image format of the texture /// @param format the image format of the texture
/// @param access the access control of the texture
/// @returns the storage texture /// @returns the storage texture
ast::StorageTexture* storage_texture(ast::TextureDimension dims, ast::StorageTexture* storage_texture(ast::TextureDimension dims,
ast::ImageFormat format) const { ast::ImageFormat format,
ast::Access access) const {
auto* subtype = ast::StorageTexture::SubtypeFor(format, *builder); auto* subtype = ast::StorageTexture::SubtypeFor(format, *builder);
return builder->create<ast::StorageTexture>(dims, format, subtype); return builder->create<ast::StorageTexture>(dims, format, subtype,
access);
} }
/// @param source the Source of the node /// @param source the Source of the node
/// @param dims the dimensionality of the texture /// @param dims the dimensionality of the texture
/// @param format the image format of the texture /// @param format the image format of the texture
/// @param access the access control of the texture
/// @returns the storage texture /// @returns the storage texture
ast::StorageTexture* storage_texture(const Source& source, ast::StorageTexture* storage_texture(const Source& source,
ast::TextureDimension dims, ast::TextureDimension dims,
ast::ImageFormat format) const { ast::ImageFormat format,
ast::Access access) const {
auto* subtype = ast::StorageTexture::SubtypeFor(format, *builder); auto* subtype = ast::StorageTexture::SubtypeFor(format, *builder);
return builder->create<ast::StorageTexture>(source, dims, format, return builder->create<ast::StorageTexture>(source, dims, format, subtype,
subtype); access);
} }
/// @returns the external texture /// @returns the external texture
@ -1216,6 +1200,7 @@ class ProgramBuilder {
/// @param optional the optional variable settings. /// @param optional the optional variable settings.
/// Can be any of the following, in any order: /// Can be any of the following, in any order:
/// * ast::StorageClass - specifies the variable storage class /// * ast::StorageClass - specifies the variable storage class
/// * ast::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression /// * ast::Expression* - specifies the variable's initializer expression
/// * ast::DecorationList - specifies the variable's decorations /// * ast::DecorationList - specifies the variable's decorations
/// Note that repeated arguments of the same type will use the last argument's /// Note that repeated arguments of the same type will use the last argument's
@ -1229,7 +1214,7 @@ class ProgramBuilder {
type = ty.MaybeCreateTypename(type); type = ty.MaybeCreateTypename(type);
VarOptionals opts(std::forward<OPTIONAL>(optional)...); VarOptionals opts(std::forward<OPTIONAL>(optional)...);
return create<ast::Variable>(Sym(std::forward<NAME>(name)), opts.storage, return create<ast::Variable>(Sym(std::forward<NAME>(name)), opts.storage,
type, false, opts.constructor, opts.access, type, false, opts.constructor,
std::move(opts.decorations)); std::move(opts.decorations));
} }
@ -1239,6 +1224,7 @@ class ProgramBuilder {
/// @param optional the optional variable settings. /// @param optional the optional variable settings.
/// Can be any of the following, in any order: /// Can be any of the following, in any order:
/// * ast::StorageClass - specifies the variable storage class /// * ast::StorageClass - specifies the variable storage class
/// * ast::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression /// * ast::Expression* - specifies the variable's initializer expression
/// * ast::DecorationList - specifies the variable's decorations /// * ast::DecorationList - specifies the variable's decorations
/// Note that repeated arguments of the same type will use the last argument's /// Note that repeated arguments of the same type will use the last argument's
@ -1252,8 +1238,8 @@ class ProgramBuilder {
type = ty.MaybeCreateTypename(type); type = ty.MaybeCreateTypename(type);
VarOptionals opts(std::forward<OPTIONAL>(optional)...); VarOptionals opts(std::forward<OPTIONAL>(optional)...);
return create<ast::Variable>(source, Sym(std::forward<NAME>(name)), return create<ast::Variable>(source, Sym(std::forward<NAME>(name)),
opts.storage, type, false, opts.constructor, opts.storage, opts.access, type, false,
std::move(opts.decorations)); opts.constructor, std::move(opts.decorations));
} }
/// @param name the variable name /// @param name the variable name
@ -1267,9 +1253,9 @@ class ProgramBuilder {
ast::Expression* constructor, ast::Expression* constructor,
ast::DecorationList decorations = {}) { ast::DecorationList decorations = {}) {
type = ty.MaybeCreateTypename(type); type = ty.MaybeCreateTypename(type);
return create<ast::Variable>(Sym(std::forward<NAME>(name)), return create<ast::Variable>(
ast::StorageClass::kNone, type, true, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
constructor, decorations); ast::Access::kUndefined, type, true, constructor, decorations);
} }
/// @param source the variable source /// @param source the variable source
@ -1285,9 +1271,9 @@ class ProgramBuilder {
ast::Expression* constructor, ast::Expression* constructor,
ast::DecorationList decorations = {}) { ast::DecorationList decorations = {}) {
type = ty.MaybeCreateTypename(type); type = ty.MaybeCreateTypename(type);
return create<ast::Variable>(source, Sym(std::forward<NAME>(name)), return create<ast::Variable>(
ast::StorageClass::kNone, type, true, source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
constructor, decorations); ast::Access::kUndefined, type, true, constructor, decorations);
} }
/// @param name the parameter name /// @param name the parameter name
@ -1299,9 +1285,9 @@ class ProgramBuilder {
ast::Type* type, ast::Type* type,
ast::DecorationList decorations = {}) { ast::DecorationList decorations = {}) {
type = ty.MaybeCreateTypename(type); type = ty.MaybeCreateTypename(type);
return create<ast::Variable>(Sym(std::forward<NAME>(name)), return create<ast::Variable>(
ast::StorageClass::kNone, type, true, nullptr, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
decorations); ast::Access::kUndefined, type, true, nullptr, decorations);
} }
/// @param source the parameter source /// @param source the parameter source
@ -1315,9 +1301,9 @@ class ProgramBuilder {
ast::Type* type, ast::Type* type,
ast::DecorationList decorations = {}) { ast::DecorationList decorations = {}) {
type = ty.MaybeCreateTypename(type); type = ty.MaybeCreateTypename(type);
return create<ast::Variable>(source, Sym(std::forward<NAME>(name)), return create<ast::Variable>(
ast::StorageClass::kNone, type, true, nullptr, source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
decorations); ast::Access::kUndefined, type, true, nullptr, decorations);
} }
/// @param name the variable name /// @param name the variable name
@ -1325,6 +1311,7 @@ class ProgramBuilder {
/// @param optional the optional variable settings. /// @param optional the optional variable settings.
/// Can be any of the following, in any order: /// Can be any of the following, in any order:
/// * ast::StorageClass - specifies the variable storage class /// * ast::StorageClass - specifies the variable storage class
/// * ast::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression /// * ast::Expression* - specifies the variable's initializer expression
/// * ast::DecorationList - specifies the variable's decorations /// * ast::DecorationList - specifies the variable's decorations
/// Note that repeated arguments of the same type will use the last argument's /// Note that repeated arguments of the same type will use the last argument's
@ -1347,6 +1334,7 @@ class ProgramBuilder {
/// @param optional the optional variable settings. /// @param optional the optional variable settings.
/// Can be any of the following, in any order: /// Can be any of the following, in any order:
/// * ast::StorageClass - specifies the variable storage class /// * ast::StorageClass - specifies the variable storage class
/// * ast::Access - specifies the variable's access control
/// * ast::Expression* - specifies the variable's initializer expression /// * ast::Expression* - specifies the variable's initializer expression
/// * ast::DecorationList - specifies the variable's decorations /// * ast::DecorationList - specifies the variable's decorations
/// Note that repeated arguments of the same type will use the last argument's /// Note that repeated arguments of the same type will use the last argument's

View File

@ -962,7 +962,7 @@ bool FunctionEmitter::EmitEntryPointAsWrapper() {
const auto param_name = namer_.MakeDerivedName(var_name + "_param"); const auto param_name = namer_.MakeDerivedName(var_name + "_param");
const auto param_sym = builder_.Symbols().Register(param_name); const auto param_sym = builder_.Symbols().Register(param_name);
auto* param = create<ast::Variable>( auto* param = create<ast::Variable>(
source, param_sym, ast::StorageClass::kNone, source, param_sym, ast::StorageClass::kNone, ast::Access::kUndefined,
forced_store_type->Build(builder_), true /* is const */, forced_store_type->Build(builder_), true /* is const */,
nullptr /* no constructor */, param_decos); nullptr /* no constructor */, param_decos);
decl.params.push_back(param); decl.params.push_back(param);
@ -2542,9 +2542,7 @@ bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
if (!guard_name.empty()) { if (!guard_name.empty()) {
// Declare the guard variable just before the "if", initialized to true. // Declare the guard variable just before the "if", initialized to true.
auto* guard_var = auto* guard_var =
create<ast::Variable>(Source{}, builder_.Symbols().Register(guard_name), builder_.Var(guard_name, builder_.ty.bool_(), MakeTrue(Source{}));
ast::StorageClass::kNone, builder_.ty.bool_(),
false, MakeTrue(Source{}), ast::DecorationList{});
auto* guard_decl = create<ast::VariableDeclStatement>(Source{}, guard_var); auto* guard_decl = create<ast::VariableDeclStatement>(Source{}, guard_var);
AddStatement(guard_decl); AddStatement(guard_decl);
} }
@ -3102,11 +3100,9 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
TINT_ASSERT(def_inst); TINT_ASSERT(def_inst);
const auto phi_var_name = GetDefInfo(id)->phi_var; const auto phi_var_name = GetDefInfo(id)->phi_var;
TINT_ASSERT(!phi_var_name.empty()); TINT_ASSERT(!phi_var_name.empty());
auto* var = create<ast::Variable>( auto* var = builder_.Var(
Source{}, builder_.Symbols().Register(phi_var_name), phi_var_name,
ast::StorageClass::kNone, parser_impl_.ConvertType(def_inst->type_id())->Build(builder_));
parser_impl_.ConvertType(def_inst->type_id())->Build(builder_), false,
nullptr, ast::DecorationList{});
AddStatement(create<ast::VariableDeclStatement>(Source{}, var)); AddStatement(create<ast::VariableDeclStatement>(Source{}, var));
} }
@ -5401,7 +5397,8 @@ bool FunctionEmitter::MakeVectorInsertDynamic(
auto* temp_var = create<ast::Variable>( auto* temp_var = create<ast::Variable>(
Source{}, registered_temp_name, ast::StorageClass::kNone, Source{}, registered_temp_name, ast::StorageClass::kNone,
ast_type->Build(builder_), false, src_vector.expr, ast::DecorationList{}); ast::Access::kUndefined, ast_type->Build(builder_), false,
src_vector.expr, ast::DecorationList{});
AddStatement(create<ast::VariableDeclStatement>(Source{}, temp_var)); AddStatement(create<ast::VariableDeclStatement>(Source{}, temp_var));
auto* lhs = create<ast::ArrayAccessorExpression>( auto* lhs = create<ast::ArrayAccessorExpression>(
@ -5429,7 +5426,7 @@ bool FunctionEmitter::MakeCompositeInsert(
// like this avoids constantly reloading the value many times. // like this avoids constantly reloading the value many times.
// //
// This technique is a combination of: // This technique is a combination of:
// - making a temporary variable and constant declaration, like what we do // - making a temporary variable and constant declaration, like what we do
// for VectorInsertDynamic, and // for VectorInsertDynamic, and
// - building up an access-chain like access like for CompositeExtract, but // - building up an access-chain like access like for CompositeExtract, but
// on the left-hand side of the assignment. // on the left-hand side of the assignment.
@ -5445,10 +5442,10 @@ bool FunctionEmitter::MakeCompositeInsert(
auto temp_name = namer_.MakeDerivedName(result_name); auto temp_name = namer_.MakeDerivedName(result_name);
auto registered_temp_name = builder_.Symbols().Register(temp_name); auto registered_temp_name = builder_.Symbols().Register(temp_name);
auto* temp_var = auto* temp_var = create<ast::Variable>(
create<ast::Variable>(Source{}, registered_temp_name, Source{}, registered_temp_name, ast::StorageClass::kNone,
ast::StorageClass::kNone, ast_type->Build(builder_), ast::Access::kUndefined, ast_type->Build(builder_), false,
false, src_composite.expr, ast::DecorationList{}); src_composite.expr, ast::DecorationList{});
AddStatement(create<ast::VariableDeclStatement>(Source{}, temp_var)); AddStatement(create<ast::VariableDeclStatement>(Source{}, temp_var));
TypedExpression seed_expr{ast_type, create<ast::IdentifierExpression>( TypedExpression seed_expr{ast_type, create<ast::IdentifierExpression>(

View File

@ -159,6 +159,7 @@ TEST_F(SpvUnaryArithTest, SNegate_Int_Int) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -187,6 +188,7 @@ TEST_F(SpvUnaryArithTest, SNegate_Int_Uint) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -217,6 +219,7 @@ TEST_F(SpvUnaryArithTest, SNegate_Uint_Int) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -247,6 +250,7 @@ TEST_F(SpvUnaryArithTest, SNegate_Uint_Uint) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -279,6 +283,7 @@ TEST_F(SpvUnaryArithTest, SNegate_SignedVec_SignedVec) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -311,6 +316,7 @@ TEST_F(SpvUnaryArithTest, SNegate_SignedVec_UnsignedVec) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -345,6 +351,7 @@ TEST_F(SpvUnaryArithTest, SNegate_UnsignedVec_SignedVec) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -379,6 +386,7 @@ TEST_F(SpvUnaryArithTest, SNegate_UnsignedVec_UnsignedVec) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -415,6 +423,7 @@ TEST_F(SpvUnaryArithTest, FNegate_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -443,6 +452,7 @@ TEST_F(SpvUnaryArithTest, FNegate_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -498,6 +508,7 @@ TEST_P(SpvBinaryArithTest, EmitExpression) {
ss << R"(VariableConst{ ss << R"(VariableConst{
x_1 x_1
none none
undefined
)" )"
<< GetParam().ast_type << "\n {\n Binary[not set]{" << GetParam().ast_type << "\n {\n Binary[not set]{"
<< "\n " << GetParam().ast_lhs << "\n " << GetParam().ast_op << "\n " << GetParam().ast_lhs << "\n " << GetParam().ast_op
@ -543,6 +554,7 @@ TEST_P(SpvBinaryArithGeneralTest, EmitExpression) {
ss << R"(VariableConst{ ss << R"(VariableConst{
x_1 x_1
none none
undefined
)" )"
<< GetParam().expected; << GetParam().expected;
auto got = ToString(p->builder(), fe.ast_body()); auto got = ToString(p->builder(), fe.ast_body());
@ -1021,6 +1033,7 @@ TEST_F(SpvBinaryArithTestBasic, SDiv_Scalar_UnsignedResult) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -1056,6 +1069,7 @@ TEST_F(SpvBinaryArithTestBasic, SDiv_Vector_UnsignedResult) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -1166,6 +1180,7 @@ TEST_F(SpvBinaryArithTestBasic, SMod_Scalar_UnsignedResult) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -1201,6 +1216,7 @@ TEST_F(SpvBinaryArithTestBasic, SMod_Vector_UnsignedResult) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -1253,6 +1269,7 @@ TEST_F(SpvBinaryArithTestBasic, VectorTimesScalar) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_10 x_10
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Binary[not set]{ Binary[not set]{
@ -1282,6 +1299,7 @@ TEST_F(SpvBinaryArithTestBasic, MatrixTimesScalar) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_10 x_10
none none
undefined
__mat_2_2__f32 __mat_2_2__f32
{ {
Binary[not set]{ Binary[not set]{
@ -1311,6 +1329,7 @@ TEST_F(SpvBinaryArithTestBasic, VectorTimesMatrix) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_10 x_10
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Binary[not set]{ Binary[not set]{
@ -1340,6 +1359,7 @@ TEST_F(SpvBinaryArithTestBasic, MatrixTimesVector) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_10 x_10
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Binary[not set]{ Binary[not set]{
@ -1369,6 +1389,7 @@ TEST_F(SpvBinaryArithTestBasic, MatrixTimesMatrix) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_10 x_10
none none
undefined
__mat_2_2__f32 __mat_2_2__f32
{ {
Binary[not set]{ Binary[not set]{
@ -1398,6 +1419,7 @@ TEST_F(SpvBinaryArithTestBasic, Dot) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_3 x_3
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -1432,6 +1454,7 @@ TEST_F(SpvBinaryArithTestBasic, OuterProduct) {
EXPECT_THAT(got, HasSubstr(R"(VariableConst{ EXPECT_THAT(got, HasSubstr(R"(VariableConst{
x_3 x_3
none none
undefined
__mat_3_2__f32 __mat_3_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1560,6 +1583,7 @@ TEST_P(SpvBinaryDerivativeTest, Derivatives) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_2 x_2
none none
undefined
)" + arg.ast_type + R"( )" + arg.ast_type + R"(
{ {
Call[not set]{ Call[not set]{
@ -1610,6 +1634,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__mat_2_2__f32 __mat_2_2__f32
{ {
Call[not set]{ Call[not set]{
@ -1648,6 +1673,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__mat_2_3__f32 __mat_2_3__f32
{ {
Call[not set]{ Call[not set]{
@ -1683,6 +1709,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__mat_3_2__f32 __mat_3_2__f32
{ {
Call[not set]{ Call[not set]{

View File

@ -163,6 +163,7 @@ TEST_P(SpvBinaryBitTest, EmitExpression) {
ss << R"(VariableConst{ ss << R"(VariableConst{
x_1 x_1
none none
undefined
)" )"
<< GetParam().ast_type << "\n {\n Binary[not set]{" << GetParam().ast_type << "\n {\n Binary[not set]{"
<< "\n " << GetParam().ast_lhs << "\n " << GetParam().ast_op << "\n " << GetParam().ast_lhs << "\n " << GetParam().ast_op
@ -208,6 +209,7 @@ TEST_P(SpvBinaryBitGeneralTest, EmitExpression) {
ss << R"(VariableConst{ ss << R"(VariableConst{
x_1 x_1
none none
undefined
)" )"
<< GetParam().expected; << GetParam().expected;
auto got = ToString(p->builder(), fe.ast_body()); auto got = ToString(p->builder(), fe.ast_body());
@ -1130,6 +1132,7 @@ TEST_F(SpvUnaryBitTest, Not_Int_Int) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1156,6 +1159,7 @@ TEST_F(SpvUnaryBitTest, Not_Int_Uint) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
Bitcast[not set]<__i32>{ Bitcast[not set]<__i32>{
@ -1184,6 +1188,7 @@ TEST_F(SpvUnaryBitTest, Not_Uint_Int) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -1212,6 +1217,7 @@ TEST_F(SpvUnaryBitTest, Not_Uint_Uint) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1238,6 +1244,7 @@ TEST_F(SpvUnaryBitTest, Not_SignedVec_SignedVec) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1268,6 +1275,7 @@ TEST_F(SpvUnaryBitTest, Not_SignedVec_UnsignedVec) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
Bitcast[not set]<__vec_2__i32>{ Bitcast[not set]<__vec_2__i32>{
@ -1300,6 +1308,7 @@ TEST_F(SpvUnaryBitTest, Not_UnsignedVec_SignedVec) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -1331,6 +1340,7 @@ TEST_F(SpvUnaryBitTest, Not_UnsignedVec_UnsignedVec) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1386,6 +1396,7 @@ TEST_F(SpvUnaryBitTest, BitCount_Uint_Uint) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{
@ -1414,6 +1425,7 @@ TEST_F(SpvUnaryBitTest, BitCount_Uint_Int) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -1444,6 +1456,7 @@ TEST_F(SpvUnaryBitTest, BitCount_Int_Uint) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
Bitcast[not set]<__i32>{ Bitcast[not set]<__i32>{
@ -1474,6 +1487,7 @@ TEST_F(SpvUnaryBitTest, BitCount_Int_Int) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
Call[not set]{ Call[not set]{
@ -1502,6 +1516,7 @@ TEST_F(SpvUnaryBitTest, BitCount_UintVector_UintVector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Call[not set]{ Call[not set]{
@ -1530,6 +1545,7 @@ TEST_F(SpvUnaryBitTest, BitCount_UintVector_IntVector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -1560,6 +1576,7 @@ TEST_F(SpvUnaryBitTest, BitCount_IntVector_UintVector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
Bitcast[not set]<__vec_2__i32>{ Bitcast[not set]<__vec_2__i32>{
@ -1590,6 +1607,7 @@ TEST_F(SpvUnaryBitTest, BitCount_IntVector_IntVector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
Call[not set]{ Call[not set]{
@ -1618,6 +1636,7 @@ TEST_F(SpvUnaryBitTest, BitReverse_Uint_Uint) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{
@ -1674,6 +1693,7 @@ TEST_F(SpvUnaryBitTest, BitReverse_Int_Int) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
Call[not set]{ Call[not set]{
@ -1702,6 +1722,7 @@ TEST_F(SpvUnaryBitTest, BitReverse_UintVector_UintVector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Call[not set]{ Call[not set]{
@ -1758,6 +1779,7 @@ TEST_F(SpvUnaryBitTest, BitReverse_IntVector_IntVector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
Call[not set]{ Call[not set]{

View File

@ -92,6 +92,7 @@ TEST_F(SpvParserTest, EmitStatement_ScalarCallNoParams) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{
@ -148,6 +149,7 @@ TEST_F(SpvParserTest, EmitStatement_ScalarCallNoParamsUsedTwice) {
Variable{ Variable{
x_10 x_10
none none
undefined
__u32 __u32
} }
} }
@ -155,6 +157,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{
@ -218,11 +221,13 @@ TEST_F(SpvParserTest, EmitStatement_CallWithParams) {
VariableConst{ VariableConst{
x_51 x_51
none none
undefined
__u32 __u32
} }
VariableConst{ VariableConst{
x_52 x_52
none none
undefined
__u32 __u32
} }
) )
@ -244,6 +249,7 @@ TEST_F(SpvParserTest, EmitStatement_CallWithParams) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{

View File

@ -7910,6 +7910,7 @@ VariableDeclStatement{
Variable{ Variable{
guard10 guard10
none none
undefined
__bool __bool
{ {
ScalarConstructor[not set]{true} ScalarConstructor[not set]{true}
@ -8022,6 +8023,7 @@ VariableDeclStatement{
Variable{ Variable{
guard10 guard10
none none
undefined
__bool __bool
{ {
ScalarConstructor[not set]{true} ScalarConstructor[not set]{true}
@ -8149,6 +8151,7 @@ VariableDeclStatement{
Variable{ Variable{
guard10 guard10
none none
undefined
__bool __bool
{ {
ScalarConstructor[not set]{true} ScalarConstructor[not set]{true}

View File

@ -92,6 +92,7 @@ TEST_F(SpvParserTest_Composite_Construct, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -106,6 +107,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -120,6 +122,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_3 x_3
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -148,6 +151,7 @@ TEST_F(SpvParserTest_Composite_Construct, Matrix) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__mat_2_3__f32 __mat_2_3__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -188,6 +192,7 @@ TEST_F(SpvParserTest_Composite_Construct, Array) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__array__u32_5 __array__u32_5
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -218,6 +223,7 @@ TEST_F(SpvParserTest_Composite_Construct, Struct) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__type_name_S __type_name_S
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -252,6 +258,7 @@ TEST_F(SpvParserTest_CompositeExtract, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
MemberAccessor[not set]{ MemberAccessor[not set]{
@ -302,6 +309,7 @@ TEST_F(SpvParserTest_CompositeExtract, Matrix) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
ArrayAccessor[not set]{ ArrayAccessor[not set]{
@ -352,6 +360,7 @@ TEST_F(SpvParserTest_CompositeExtract, Matrix_Vector) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__f32 __f32
{ {
MemberAccessor[not set]{ MemberAccessor[not set]{
@ -385,6 +394,7 @@ TEST_F(SpvParserTest_CompositeExtract, Array) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
ArrayAccessor[not set]{ ArrayAccessor[not set]{
@ -436,6 +446,7 @@ TEST_F(SpvParserTest_CompositeExtract, Struct) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__i32 __i32
{ {
MemberAccessor[not set]{ MemberAccessor[not set]{
@ -478,6 +489,7 @@ TEST_F(SpvParserTest_CompositeExtract, Struct_DifferOnlyInMemberName) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
MemberAccessor[not set]{ MemberAccessor[not set]{
@ -491,6 +503,7 @@ TEST_F(SpvParserTest_CompositeExtract, Struct_DifferOnlyInMemberName) {
VariableConst{ VariableConst{
x_4 x_4
none none
undefined
__u32 __u32
{ {
MemberAccessor[not set]{ MemberAccessor[not set]{
@ -544,6 +557,7 @@ TEST_F(SpvParserTest_CompositeExtract, Struct_Array_Matrix_Vector) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__f32 __f32
{ {
MemberAccessor[not set]{ MemberAccessor[not set]{
@ -582,6 +596,7 @@ TEST_F(SpvParserTest_CompositeInsert, Vector) {
Variable{ Variable{
x_1_1 x_1_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -603,6 +618,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Identifier[not set]{x_1_1} Identifier[not set]{x_1_1}
@ -648,6 +664,7 @@ TEST_F(SpvParserTest_CompositeInsert, Matrix) {
Variable{ Variable{
x_2_1 x_2_1
none none
undefined
__mat_2_3__f32 __mat_2_3__f32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -669,6 +686,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__mat_2_3__f32 __mat_2_3__f32
{ {
Identifier[not set]{x_2_1} Identifier[not set]{x_2_1}
@ -718,6 +736,7 @@ TEST_F(SpvParserTest_CompositeInsert, Matrix_Vector) {
Variable{ Variable{
x_2_1 x_2_1
none none
undefined
__mat_2_3__f32 __mat_2_3__f32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -739,6 +758,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__mat_2_3__f32 __mat_2_3__f32
{ {
Identifier[not set]{x_2_1} Identifier[not set]{x_2_1}
@ -768,6 +788,7 @@ TEST_F(SpvParserTest_CompositeInsert, Array) {
Variable{ Variable{
x_2_1 x_2_1
none none
undefined
__array__u32_5 __array__u32_5
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -785,6 +806,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__array__u32_5 __array__u32_5
{ {
Identifier[not set]{x_2_1} Identifier[not set]{x_2_1}
@ -835,6 +857,7 @@ TEST_F(SpvParserTest_CompositeInsert, Struct) {
Variable{ Variable{
x_35 x_35
none none
undefined
__type_name_S __type_name_S
} }
} }
@ -842,6 +865,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__type_name_S __type_name_S
{ {
Identifier[not set]{x_35} Identifier[not set]{x_35}
@ -852,6 +876,7 @@ VariableDeclStatement{
Variable{ Variable{
x_2_1 x_2_1
none none
undefined
__type_name_S __type_name_S
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -869,6 +894,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__type_name_S __type_name_S
{ {
Identifier[not set]{x_2_1} Identifier[not set]{x_2_1}
@ -909,6 +935,7 @@ TEST_F(SpvParserTest_CompositeInsert, Struct_DifferOnlyInMemberName) {
Variable{ Variable{
x_40 x_40
none none
undefined
__type_name_S_2 __type_name_S_2
} }
} }
@ -916,6 +943,7 @@ VariableDeclStatement{
Variable{ Variable{
x_41 x_41
none none
undefined
__type_name_S_2 __type_name_S_2
} }
} }
@ -923,6 +951,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__type_name_S_2 __type_name_S_2
{ {
Identifier[not set]{x_40} Identifier[not set]{x_40}
@ -933,6 +962,7 @@ VariableDeclStatement{
Variable{ Variable{
x_2_1 x_2_1
none none
undefined
__type_name_S_1 __type_name_S_1
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -950,6 +980,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__type_name_S_1 __type_name_S_1
{ {
Identifier[not set]{x_2_1} Identifier[not set]{x_2_1}
@ -960,6 +991,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_3 x_3
none none
undefined
__type_name_S_2 __type_name_S_2
{ {
Identifier[not set]{x_41} Identifier[not set]{x_41}
@ -970,6 +1002,7 @@ VariableDeclStatement{
Variable{ Variable{
x_4_1 x_4_1
none none
undefined
__type_name_S_2 __type_name_S_2
{ {
Identifier[not set]{x_3} Identifier[not set]{x_3}
@ -987,6 +1020,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_4 x_4
none none
undefined
__type_name_S_2 __type_name_S_2
{ {
Identifier[not set]{x_4_1} Identifier[not set]{x_4_1}
@ -998,6 +1032,7 @@ VariableDeclStatement{
Variable{ Variable{
x_4_1 x_4_1
none none
undefined
__type_name_S_2 __type_name_S_2
{ {
Identifier[not set]{x_3} Identifier[not set]{x_3}
@ -1015,6 +1050,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_4 x_4
none none
undefined
__type_name_S_2 __type_name_S_2
{ {
Identifier[not set]{x_4_1} Identifier[not set]{x_4_1}
@ -1066,6 +1102,7 @@ TEST_F(SpvParserTest_CompositeInsert, Struct_Array_Matrix_Vector) {
Variable{ Variable{
x_37 x_37
none none
undefined
__type_name_S_1 __type_name_S_1
} }
} }
@ -1073,6 +1110,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__type_name_S_1 __type_name_S_1
{ {
Identifier[not set]{x_37} Identifier[not set]{x_37}
@ -1083,6 +1121,7 @@ VariableDeclStatement{
Variable{ Variable{
x_2_1 x_2_1
none none
undefined
__type_name_S_1 __type_name_S_1
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -1109,6 +1148,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__type_name_S_1 __type_name_S_1
{ {
Identifier[not set]{x_2_1} Identifier[not set]{x_2_1}
@ -1137,6 +1177,7 @@ TEST_F(SpvParserTest_CopyObject, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{3u} ScalarConstructor[not set]{3u}
@ -1147,6 +1188,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -1176,6 +1218,7 @@ TEST_F(SpvParserTest_CopyObject, Pointer) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__ptr_function__u32 __ptr_function__u32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1189,6 +1232,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__ptr_function__u32 __ptr_function__u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -1218,6 +1262,7 @@ TEST_F(SpvParserTest_VectorShuffle, FunctionScopeOperands_UseBoth) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_10 x_10
none none
undefined
__vec_4__u32 __vec_4__u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1260,6 +1305,7 @@ TEST_F(SpvParserTest_VectorShuffle, ConstantOperands_UseBoth) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_10 x_10
none none
undefined
__vec_4__u32 __vec_4__u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1318,6 +1364,7 @@ TEST_F(SpvParserTest_VectorShuffle, ConstantOperands_AllOnesMapToNull) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_10 x_10
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1370,6 +1417,7 @@ TEST_F(SpvParserTest_VectorExtractDynamic, SignedIndex) {
EXPECT_THAT(got, HasSubstr(R"(VariableConst{ EXPECT_THAT(got, HasSubstr(R"(VariableConst{
x_10 x_10
none none
undefined
__u32 __u32
{ {
ArrayAccessor[not set]{ ArrayAccessor[not set]{
@ -1400,6 +1448,7 @@ TEST_F(SpvParserTest_VectorExtractDynamic, UnsignedIndex) {
EXPECT_THAT(got, HasSubstr(R"(VariableConst{ EXPECT_THAT(got, HasSubstr(R"(VariableConst{
x_10 x_10
none none
undefined
__u32 __u32
{ {
ArrayAccessor[not set]{ ArrayAccessor[not set]{
@ -1435,6 +1484,7 @@ VariableDeclStatement{
Variable{ Variable{
x_10_1 x_10_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -1452,6 +1502,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_10 x_10
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Identifier[not set]{x_10_1} Identifier[not set]{x_10_1}

View File

@ -86,6 +86,7 @@ TEST_F(SpvUnaryConversionTest, Bitcast_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -111,6 +112,7 @@ TEST_F(SpvUnaryConversionTest, Bitcast_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Bitcast[not set]<__vec_2__f32>{ Bitcast[not set]<__vec_2__f32>{
@ -239,6 +241,7 @@ TEST_F(SpvUnaryConversionTest, ConvertSToF_Scalar_FromSigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -265,6 +268,7 @@ TEST_F(SpvUnaryConversionTest, ConvertSToF_Scalar_FromUnsigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -293,6 +297,7 @@ TEST_F(SpvUnaryConversionTest, ConvertSToF_Vector_FromSigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -319,6 +324,7 @@ TEST_F(SpvUnaryConversionTest, ConvertSToF_Vector_FromUnsigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -382,6 +388,7 @@ TEST_F(SpvUnaryConversionTest, ConvertUToF_Scalar_FromSigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -410,6 +417,7 @@ TEST_F(SpvUnaryConversionTest, ConvertUToF_Scalar_FromUnsigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -436,6 +444,7 @@ TEST_F(SpvUnaryConversionTest, ConvertUToF_Vector_FromSigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -464,6 +473,7 @@ TEST_F(SpvUnaryConversionTest, ConvertUToF_Vector_FromUnsigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -526,6 +536,7 @@ TEST_F(SpvUnaryConversionTest, ConvertFToS_Scalar_ToSigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -552,6 +563,7 @@ TEST_F(SpvUnaryConversionTest, ConvertFToS_Scalar_ToUnsigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -580,6 +592,7 @@ TEST_F(SpvUnaryConversionTest, ConvertFToS_Vector_ToSigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -606,6 +619,7 @@ TEST_F(SpvUnaryConversionTest, ConvertFToS_Vector_ToUnsigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -686,6 +700,7 @@ TEST_F(SpvUnaryConversionTest, ConvertFToU_Scalar_ToUnsigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -728,6 +743,7 @@ TEST_F(SpvUnaryConversionTest, ConvertFToU_Vector_ToUnsigned) {
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -778,6 +794,7 @@ OpFunctionEnd
EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{ EXPECT_THAT(ToString(p->builder(), fe.ast_body()), HasSubstr(R"(VariableConst{
x_82 x_82
none none
undefined
__u32 __u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{

View File

@ -118,16 +118,19 @@ TEST_F(SpvParserTest, Emit_MixedParamTypes) {
VariableConst{ VariableConst{
a a
none none
undefined
__u32 __u32
} }
VariableConst{ VariableConst{
b b
none none
undefined
__f32 __f32
} }
VariableConst{ VariableConst{
c c
none none
undefined
__i32 __i32
} }
) )
@ -162,16 +165,19 @@ TEST_F(SpvParserTest, Emit_GenerateParamNames) {
VariableConst{ VariableConst{
x_14 x_14
none none
undefined
__u32 __u32
} }
VariableConst{ VariableConst{
x_15 x_15
none none
undefined
__f32 __f32
} }
VariableConst{ VariableConst{
x_16 x_16
none none
undefined
__i32 __i32
} }
) )

View File

@ -188,6 +188,7 @@ TEST_P(SpvParserTest_GlslStd450_Float_Floating, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -219,6 +220,7 @@ TEST_P(SpvParserTest_GlslStd450_Float_Floating, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -250,6 +252,7 @@ TEST_P(SpvParserTest_GlslStd450_Float_FloatingFloating, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -282,6 +285,7 @@ TEST_P(SpvParserTest_GlslStd450_Float_FloatingFloating, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -314,6 +318,7 @@ TEST_P(SpvParserTest_GlslStd450_Floating_Floating, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -345,6 +350,7 @@ TEST_P(SpvParserTest_GlslStd450_Floating_Floating, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Call[not set]{ Call[not set]{
@ -376,6 +382,7 @@ TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloating, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -408,6 +415,7 @@ TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloating, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Call[not set]{ Call[not set]{
@ -440,6 +448,7 @@ TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -474,6 +483,7 @@ TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Call[not set]{ Call[not set]{
@ -507,6 +517,7 @@ TEST_P(SpvParserTest_GlslStd450_Floating_FloatingUinting, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -540,6 +551,7 @@ TEST_P(SpvParserTest_GlslStd450_Floating_FloatingUinting, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Call[not set]{ Call[not set]{
@ -572,6 +584,7 @@ TEST_P(SpvParserTest_GlslStd450_Floating_FloatingInting, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -605,6 +618,7 @@ TEST_P(SpvParserTest_GlslStd450_Floating_FloatingInting, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Call[not set]{ Call[not set]{
@ -638,6 +652,7 @@ TEST_P(SpvParserTest_GlslStd450_Float3_Float3Float3, Samples) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_3__f32 __vec_3__f32
{ {
Call[not set]{ Call[not set]{
@ -744,6 +759,7 @@ TEST_P(SpvParserTest_GlslStd450_Inting_Inting, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
Call[not set]{ Call[not set]{
@ -776,6 +792,7 @@ TEST_P(SpvParserTest_GlslStd450_Inting_Inting, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
Call[not set]{ Call[not set]{
@ -808,6 +825,7 @@ TEST_P(SpvParserTest_GlslStd450_Inting_IntingInting, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
Call[not set]{ Call[not set]{
@ -841,6 +859,7 @@ TEST_P(SpvParserTest_GlslStd450_Inting_IntingInting, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
Call[not set]{ Call[not set]{
@ -874,6 +893,7 @@ TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
Call[not set]{ Call[not set]{
@ -908,6 +928,7 @@ TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
Call[not set]{ Call[not set]{
@ -954,6 +975,7 @@ TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUinting, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{
@ -987,6 +1009,7 @@ TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUinting, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Call[not set]{ Call[not set]{
@ -1019,6 +1042,7 @@ TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting, Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{
@ -1053,6 +1077,7 @@ TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting, Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Call[not set]{ Call[not set]{
@ -1099,6 +1124,7 @@ TEST_F(SpvParserTest, Normalize_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
ScalarConstructor[not set]{1.000000} ScalarConstructor[not set]{1.000000}
@ -1123,6 +1149,7 @@ TEST_F(SpvParserTest, Normalize_Vector2) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
Call[not set]{ Call[not set]{
@ -1152,6 +1179,7 @@ TEST_F(SpvParserTest, Normalize_Vector3) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_3__f32 __vec_3__f32
{ {
Call[not set]{ Call[not set]{
@ -1181,6 +1209,7 @@ TEST_F(SpvParserTest, Normalize_Vector4) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_4__f32 __vec_4__f32
{ {
Call[not set]{ Call[not set]{
@ -1213,6 +1242,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_SAbs) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -1232,6 +1262,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_SAbs) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -1265,6 +1296,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_SMax) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -1287,6 +1319,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_SMax) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -1323,6 +1356,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_SMin) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -1345,6 +1379,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_SMin) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -1381,6 +1416,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_SClamp) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Bitcast[not set]<__u32>{ Bitcast[not set]<__u32>{
@ -1404,6 +1440,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_SClamp) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Bitcast[not set]<__vec_2__u32>{ Bitcast[not set]<__vec_2__u32>{
@ -1441,6 +1478,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_UMax) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
Bitcast[not set]<__i32>{ Bitcast[not set]<__i32>{
@ -1463,6 +1501,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_UMax) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
Bitcast[not set]<__vec_2__i32>{ Bitcast[not set]<__vec_2__i32>{
@ -1499,6 +1538,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_UMin) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
Bitcast[not set]<__i32>{ Bitcast[not set]<__i32>{
@ -1521,6 +1561,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_UMin) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
Bitcast[not set]<__vec_2__i32>{ Bitcast[not set]<__vec_2__i32>{
@ -1557,6 +1598,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_UClamp) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__i32 __i32
{ {
Bitcast[not set]<__i32>{ Bitcast[not set]<__i32>{
@ -1580,6 +1622,7 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_UClamp) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
Bitcast[not set]<__vec_2__i32>{ Bitcast[not set]<__vec_2__i32>{
@ -1633,6 +1676,7 @@ TEST_P(SpvParserTest_GlslStd450_DataPacking, Valid) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{
@ -1677,6 +1721,7 @@ TEST_P(SpvParserTest_GlslStd450_DataUnpacking, Valid) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
)" + std::string(param.vec_size == 2 ? "__vec_2__f32" : "__vec_4__f32") + )" + std::string(param.vec_size == 2 ? "__vec_2__f32" : "__vec_4__f32") +
R"( R"(
{ {

View File

@ -210,6 +210,7 @@ TEST_F(SpvUnaryLogicalTest, LogicalNot_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -236,6 +237,7 @@ TEST_F(SpvUnaryLogicalTest, LogicalNot_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__bool __vec_2__bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -290,6 +292,7 @@ TEST_P(SpvBinaryLogicalTest, EmitExpression) {
ss << R"(VariableConst{ ss << R"(VariableConst{
x_1 x_1
none none
undefined
)" )"
<< GetParam().ast_type << "\n {\n Binary[not set]{" << GetParam().ast_type << "\n {\n Binary[not set]{"
<< "\n " << GetParam().ast_lhs << "\n " << GetParam().ast_op << "\n " << GetParam().ast_lhs << "\n " << GetParam().ast_op
@ -728,6 +731,7 @@ TEST_F(SpvFUnordTest, FUnordEqual_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -758,6 +762,7 @@ TEST_F(SpvFUnordTest, FUnordEqual_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__bool __vec_2__bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -796,6 +801,7 @@ TEST_F(SpvFUnordTest, FUnordNotEqual_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -826,6 +832,7 @@ TEST_F(SpvFUnordTest, FUnordNotEqual_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__bool __vec_2__bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -864,6 +871,7 @@ TEST_F(SpvFUnordTest, FUnordLessThan_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -894,6 +902,7 @@ TEST_F(SpvFUnordTest, FUnordLessThan_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__bool __vec_2__bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -932,6 +941,7 @@ TEST_F(SpvFUnordTest, FUnordLessThanEqual_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -962,6 +972,7 @@ TEST_F(SpvFUnordTest, FUnordLessThanEqual_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__bool __vec_2__bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1000,6 +1011,7 @@ TEST_F(SpvFUnordTest, FUnordGreaterThan_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1030,6 +1042,7 @@ TEST_F(SpvFUnordTest, FUnordGreaterThan_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__bool __vec_2__bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1068,6 +1081,7 @@ TEST_F(SpvFUnordTest, FUnordGreaterThanEqual_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1098,6 +1112,7 @@ TEST_F(SpvFUnordTest, FUnordGreaterThanEqual_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__bool __vec_2__bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1139,6 +1154,7 @@ TEST_F(SpvLogicalTest, Select_BoolCond_BoolParams) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
Call[not set]{ Call[not set]{
@ -1171,6 +1187,7 @@ TEST_F(SpvLogicalTest, Select_BoolCond_IntScalarParams) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{
@ -1203,6 +1220,7 @@ TEST_F(SpvLogicalTest, Select_BoolCond_FloatScalarParams) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__f32 __f32
{ {
Call[not set]{ Call[not set]{
@ -1238,6 +1256,7 @@ TEST_F(SpvLogicalTest, Select_BoolCond_VectorParams) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Call[not set]{ Call[not set]{
@ -1284,6 +1303,7 @@ TEST_F(SpvLogicalTest, Select_VecBoolCond_VectorParams) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
Call[not set]{ Call[not set]{
@ -1328,6 +1348,7 @@ TEST_F(SpvLogicalTest, Any) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
Call[not set]{ Call[not set]{
@ -1362,6 +1383,7 @@ TEST_F(SpvLogicalTest, All) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
Call[not set]{ Call[not set]{
@ -1396,6 +1418,7 @@ TEST_F(SpvLogicalTest, IsNan_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
Call[not set]{ Call[not set]{
@ -1426,6 +1449,7 @@ TEST_F(SpvLogicalTest, IsNan_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__bool __vec_2__bool
{ {
Call[not set]{ Call[not set]{
@ -1460,6 +1484,7 @@ TEST_F(SpvLogicalTest, IsInf_Scalar) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__bool __bool
{ {
Call[not set]{ Call[not set]{
@ -1490,6 +1515,7 @@ TEST_F(SpvLogicalTest, IsInf_Vector) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__vec_2__bool __vec_2__bool
{ {
Call[not set]{ Call[not set]{

View File

@ -180,6 +180,7 @@ TEST_F(SpvParserMemoryTest, EmitStatement_LoadBool) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -210,6 +211,7 @@ TEST_F(SpvParserMemoryTest, EmitStatement_LoadScalar) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -220,6 +222,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_3 x_3
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -252,6 +255,7 @@ TEST_F(SpvParserMemoryTest, EmitStatement_UseLoadedScalarTwice) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -873,7 +877,8 @@ TEST_F(SpvParserMemoryTest, RemapStorageBuffer_TypesAndVarDeclarations) {
} }
myvar myvar
storage storage
__access_control_read_write__type_name_S read_write
__type_name_S
})")); })"));
} }
@ -1017,6 +1022,7 @@ TEST_F(SpvParserMemoryTest,
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__ptr_storage__u32 __ptr_storage__u32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -1078,6 +1084,7 @@ TEST_F(SpvParserMemoryTest, RemapStorageBuffer_ThroughCopyObject_WithHoisting) {
Variable{ Variable{
x_2 x_2
none none
undefined
__ptr_storage__u32 __ptr_storage__u32
} }
} }
@ -1176,6 +1183,7 @@ TEST_F(SpvParserMemoryTest, ArrayLength) {
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{

View File

@ -78,6 +78,7 @@ TEST_F(SpvParserTestMiscInstruction, OpUndef_BeforeFunction_Scalar) {
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__bool __bool
{ {
ScalarConstructor[not set]{false} ScalarConstructor[not set]{false}
@ -88,6 +89,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_12 x_12
none none
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{0u} ScalarConstructor[not set]{0u}
@ -98,6 +100,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_13 x_13
none none
undefined
__i32 __i32
{ {
ScalarConstructor[not set]{0} ScalarConstructor[not set]{0}
@ -108,6 +111,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_14 x_14
none none
undefined
__f32 __f32
{ {
ScalarConstructor[not set]{0.000000} ScalarConstructor[not set]{0.000000}
@ -142,6 +146,7 @@ TEST_F(SpvParserTestMiscInstruction, OpUndef_BeforeFunction_Vector) {
VariableConst{ VariableConst{
x_14 x_14
none none
undefined
__vec_2__bool __vec_2__bool
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -156,6 +161,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -170,6 +176,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_12 x_12
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -184,6 +191,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_13 x_13
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -221,6 +229,7 @@ TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Scalar) {
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__bool __bool
{ {
ScalarConstructor[not set]{false} ScalarConstructor[not set]{false}
@ -231,6 +240,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_12 x_12
none none
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{0u} ScalarConstructor[not set]{0u}
@ -241,6 +251,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_13 x_13
none none
undefined
__i32 __i32
{ {
ScalarConstructor[not set]{0} ScalarConstructor[not set]{0}
@ -251,6 +262,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_14 x_14
none none
undefined
__f32 __f32
{ {
ScalarConstructor[not set]{0.000000} ScalarConstructor[not set]{0.000000}
@ -282,6 +294,7 @@ TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Vector) {
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__vec_2__u32 __vec_2__u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -296,6 +309,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_12 x_12
none none
undefined
__vec_2__i32 __vec_2__i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -310,6 +324,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_13 x_13
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -343,6 +358,7 @@ TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Matrix) {
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__mat_2_2__f32 __mat_2_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -385,6 +401,7 @@ TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Array) {
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__array__u32_2 __array__u32_2
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -418,6 +435,7 @@ TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Struct) {
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__type_name_S __type_name_S
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -541,6 +559,7 @@ TEST_F(SpvParserTest, ValueFromBlockNotInBlockOrder) {
VariableConst{ VariableConst{
x_81 x_81
none none
undefined
__f32 __f32
{ {
Binary[not set]{ Binary[not set]{

View File

@ -108,6 +108,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_AnonymousVars) {
Variable{ Variable{
x_1 x_1
none none
undefined
__u32 __u32
} }
} }
@ -115,6 +116,7 @@ VariableDeclStatement{
Variable{ Variable{
x_2 x_2
none none
undefined
__u32 __u32
} }
} }
@ -122,6 +124,7 @@ VariableDeclStatement{
Variable{ Variable{
x_3 x_3
none none
undefined
__u32 __u32
} }
} }
@ -147,6 +150,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_NamedVars) {
Variable{ Variable{
a a
none none
undefined
__u32 __u32
} }
} }
@ -154,6 +158,7 @@ VariableDeclStatement{
Variable{ Variable{
b b
none none
undefined
__u32 __u32
} }
} }
@ -161,6 +166,7 @@ VariableDeclStatement{
Variable{ Variable{
c c
none none
undefined
__u32 __u32
} }
} }
@ -186,6 +192,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_MixedTypes) {
Variable{ Variable{
a a
none none
undefined
__u32 __u32
} }
} }
@ -193,6 +200,7 @@ VariableDeclStatement{
Variable{ Variable{
b b
none none
undefined
__i32 __i32
} }
} }
@ -200,6 +208,7 @@ VariableDeclStatement{
Variable{ Variable{
c c
none none
undefined
__f32 __f32
} }
} }
@ -227,6 +236,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_ScalarInitializers) {
Variable{ Variable{
a a
none none
undefined
__bool __bool
{ {
ScalarConstructor[not set]{true} ScalarConstructor[not set]{true}
@ -237,6 +247,7 @@ VariableDeclStatement{
Variable{ Variable{
b b
none none
undefined
__bool __bool
{ {
ScalarConstructor[not set]{false} ScalarConstructor[not set]{false}
@ -247,6 +258,7 @@ VariableDeclStatement{
Variable{ Variable{
c c
none none
undefined
__i32 __i32
{ {
ScalarConstructor[not set]{-1} ScalarConstructor[not set]{-1}
@ -257,6 +269,7 @@ VariableDeclStatement{
Variable{ Variable{
d d
none none
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{1u} ScalarConstructor[not set]{1u}
@ -267,6 +280,7 @@ VariableDeclStatement{
Variable{ Variable{
e e
none none
undefined
__f32 __f32
{ {
ScalarConstructor[not set]{1.500000} ScalarConstructor[not set]{1.500000}
@ -301,6 +315,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_ScalarNullInitializers) {
Variable{ Variable{
a a
none none
undefined
__bool __bool
{ {
ScalarConstructor[not set]{false} ScalarConstructor[not set]{false}
@ -311,6 +326,7 @@ VariableDeclStatement{
Variable{ Variable{
b b
none none
undefined
__i32 __i32
{ {
ScalarConstructor[not set]{0} ScalarConstructor[not set]{0}
@ -321,6 +337,7 @@ VariableDeclStatement{
Variable{ Variable{
c c
none none
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{0u} ScalarConstructor[not set]{0u}
@ -331,6 +348,7 @@ VariableDeclStatement{
Variable{ Variable{
d d
none none
undefined
__f32 __f32
{ {
ScalarConstructor[not set]{0.000000} ScalarConstructor[not set]{0.000000}
@ -361,6 +379,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_VectorInitializer) {
Variable{ Variable{
x_200 x_200
none none
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -400,6 +419,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_MatrixInitializer) {
Variable{ Variable{
x_200 x_200
none none
undefined
__mat_2_3__f32 __mat_2_3__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -447,6 +467,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_ArrayInitializer) {
Variable{ Variable{
x_200 x_200
none none
undefined
__array__u32_2 __array__u32_2
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -486,6 +507,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_ArrayInitializer_Alias) {
Variable{ Variable{
x_200 x_200
none none
undefined
__type_name_Arr __type_name_Arr
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -521,6 +543,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_ArrayInitializer_Null) {
Variable{ Variable{
x_200 x_200
none none
undefined
__array__u32_2 __array__u32_2
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -561,6 +584,7 @@ TEST_F(SpvParserFunctionVarTest,
Variable{ Variable{
x_200 x_200
none none
undefined
__type_name_Arr __type_name_Arr
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -596,6 +620,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_StructInitializer) {
Variable{ Variable{
x_200 x_200
none none
undefined
__type_name_S __type_name_S
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -636,6 +661,7 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_StructInitializer_Null) {
Variable{ Variable{
x_200 x_200
none none
undefined
__type_name_S __type_name_S
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -682,6 +708,7 @@ TEST_F(SpvParserFunctionVarTest,
Variable{ Variable{
x_25 x_25
none none
undefined
__u32 __u32
} }
} }
@ -730,6 +757,7 @@ TEST_F(SpvParserFunctionVarTest,
Variable{ Variable{
x_25 x_25
none none
undefined
__u32 __u32
} }
} }
@ -737,6 +765,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Binary[not set]{ Binary[not set]{
@ -802,6 +831,7 @@ TEST_F(SpvParserFunctionVarTest,
Variable{ Variable{
x_25 x_25
none none
undefined
__u32 __u32
} }
} }
@ -809,6 +839,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Binary[not set]{ Binary[not set]{
@ -906,6 +937,7 @@ Loop{
Variable{ Variable{
x_2 x_2
none none
undefined
__u32 __u32
} }
} }
@ -1019,6 +1051,7 @@ TEST_F(
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{1u} ScalarConstructor[not set]{1u}
@ -1036,6 +1069,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_3 x_3
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -1109,6 +1143,7 @@ TEST_F(SpvParserFunctionVarTest,
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{1u} ScalarConstructor[not set]{1u}
@ -1126,6 +1161,7 @@ TEST_F(SpvParserFunctionVarTest,
VariableConst{ VariableConst{
x_3 x_3
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -1196,6 +1232,7 @@ TEST_F(
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{1u} ScalarConstructor[not set]{1u}
@ -1215,6 +1252,7 @@ TEST_F(
VariableConst{ VariableConst{
x_3 x_3
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -1274,6 +1312,7 @@ TEST_F(SpvParserFunctionVarTest,
VariableConst{ VariableConst{
x_1 x_1
none none
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{1u} ScalarConstructor[not set]{1u}
@ -1284,6 +1323,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -1352,6 +1392,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_SingleBlockLoopIndex) {
Variable{ Variable{
x_2_phi x_2_phi
none none
undefined
__u32 __u32
} }
} }
@ -1359,6 +1400,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_SingleBlockLoopIndex) {
Variable{ Variable{
x_3_phi x_3_phi
none none
undefined
__u32 __u32
} }
} }
@ -1366,6 +1408,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_SingleBlockLoopIndex) {
VariableConst{ VariableConst{
x_101 x_101
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_7} Identifier[not set]{x_7}
@ -1376,6 +1419,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_SingleBlockLoopIndex) {
VariableConst{ VariableConst{
x_102 x_102
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_8} Identifier[not set]{x_8}
@ -1403,6 +1447,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_SingleBlockLoopIndex) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_2_phi} Identifier[not set]{x_2_phi}
@ -1413,6 +1458,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_SingleBlockLoopIndex) {
VariableConst{ VariableConst{
x_3 x_3
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_3_phi} Identifier[not set]{x_3_phi}
@ -1499,6 +1545,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_MultiBlockLoopIndex) {
Variable{ Variable{
x_2_phi x_2_phi
none none
undefined
__u32 __u32
} }
} }
@ -1506,6 +1553,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_MultiBlockLoopIndex) {
Variable{ Variable{
x_3_phi x_3_phi
none none
undefined
__u32 __u32
} }
} }
@ -1513,6 +1561,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_MultiBlockLoopIndex) {
VariableConst{ VariableConst{
x_101 x_101
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_7} Identifier[not set]{x_7}
@ -1523,6 +1572,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_MultiBlockLoopIndex) {
VariableConst{ VariableConst{
x_102 x_102
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_8} Identifier[not set]{x_8}
@ -1550,6 +1600,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_MultiBlockLoopIndex) {
Variable{ Variable{
x_4 x_4
none none
undefined
__u32 __u32
} }
} }
@ -1557,6 +1608,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_MultiBlockLoopIndex) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_2_phi} Identifier[not set]{x_2_phi}
@ -1567,6 +1619,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_MultiBlockLoopIndex) {
VariableConst{ VariableConst{
x_3 x_3
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_3_phi} Identifier[not set]{x_3_phi}
@ -1660,6 +1713,7 @@ TEST_F(SpvParserFunctionVarTest,
VariableConst{ VariableConst{
x_101 x_101
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_17} Identifier[not set]{x_17}
@ -1671,6 +1725,7 @@ Loop{
Variable{ Variable{
x_2_phi x_2_phi
none none
undefined
__u32 __u32
} }
} }
@ -1678,6 +1733,7 @@ Loop{
Variable{ Variable{
x_5_phi x_5_phi
none none
undefined
__u32 __u32
} }
} }
@ -1694,6 +1750,7 @@ Loop{
Variable{ Variable{
x_7 x_7
none none
undefined
__u32 __u32
} }
} }
@ -1701,6 +1758,7 @@ Loop{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_2_phi} Identifier[not set]{x_2_phi}
@ -1711,6 +1769,7 @@ Loop{
VariableConst{ VariableConst{
x_5 x_5
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_5_phi} Identifier[not set]{x_5_phi}
@ -1721,6 +1780,7 @@ Loop{
VariableConst{ VariableConst{
x_4 x_4
none none
undefined
__u32 __u32
{ {
Binary[not set]{ Binary[not set]{
@ -1735,6 +1795,7 @@ Loop{
VariableConst{ VariableConst{
x_6 x_6
none none
undefined
__u32 __u32
{ {
Binary[not set]{ Binary[not set]{
@ -1832,6 +1893,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_FromElseAndThen) {
VariableConst{ VariableConst{
x_101 x_101
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_7} Identifier[not set]{x_7}
@ -1842,6 +1904,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_102 x_102
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_8} Identifier[not set]{x_8}
@ -1853,6 +1916,7 @@ Loop{
Variable{ Variable{
x_2_phi x_2_phi
none none
undefined
__u32 __u32
} }
} }
@ -1890,6 +1954,7 @@ Loop{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_2_phi} Identifier[not set]{x_2_phi}
@ -1958,6 +2023,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_FromHeaderAndThen) {
VariableConst{ VariableConst{
x_101 x_101
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_7} Identifier[not set]{x_7}
@ -1968,6 +2034,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_102 x_102
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_8} Identifier[not set]{x_8}
@ -1979,6 +2046,7 @@ Loop{
Variable{ Variable{
x_2_phi x_2_phi
none none
undefined
__u32 __u32
} }
} }
@ -2017,6 +2085,7 @@ Loop{
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_2_phi} Identifier[not set]{x_2_phi}
@ -2084,6 +2153,7 @@ TEST_F(SpvParserFunctionVarTest,
Variable{ Variable{
x_35_phi x_35_phi
none none
undefined
__u32 __u32
} }
} }
@ -2124,6 +2194,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_35 x_35
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_35_phi} Identifier[not set]{x_35_phi}
@ -2174,6 +2245,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_UseInPhiCountsAsUse) {
Variable{ Variable{
x_101_phi x_101_phi
none none
undefined
__bool __bool
} }
} }
@ -2181,6 +2253,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__bool __bool
{ {
Binary[not set]{ Binary[not set]{
@ -2195,6 +2268,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_12 x_12
none none
undefined
__bool __bool
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -2223,6 +2297,7 @@ VariableDeclStatement{
VariableConst{ VariableConst{
x_101 x_101
none none
undefined
__bool __bool
{ {
Identifier[not set]{x_101_phi} Identifier[not set]{x_101_phi}
@ -2291,6 +2366,7 @@ TEST_F(SpvParserFunctionVarTest,
Variable{ Variable{
x_81_phi_1 x_81_phi_1
none none
undefined
__f32 __f32
} }
} }
@ -2298,6 +2374,7 @@ TEST_F(SpvParserFunctionVarTest,
VariableConst{ VariableConst{
x_81 x_81
none none
undefined
__f32 __f32
{ {
Identifier[not set]{x_81_phi_1} Identifier[not set]{x_81_phi_1}

View File

@ -1354,6 +1354,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
return nullptr; return nullptr;
} }
ast::Access access = ast::Access::kUndefined;
if (sc == ast::StorageClass::kStorage) { if (sc == ast::StorageClass::kStorage) {
bool read_only = false; bool read_only = false;
if (auto* tn = storage_type->As<Named>()) { if (auto* tn = storage_type->As<Named>()) {
@ -1361,9 +1362,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
} }
// Apply the access(read) or access(read_write) modifier. // Apply the access(read) or access(read_write) modifier.
auto access = access = read_only ? ast::Access::kRead : ast::Access::kReadWrite;
read_only ? ast::AccessControl::kRead : ast::AccessControl::kReadWrite;
storage_type = ty_.AccessControl(storage_type, access);
} }
// Handle variables (textures and samplers) are always in the handle // Handle variables (textures and samplers) are always in the handle
@ -1387,7 +1386,7 @@ ast::Variable* ParserImpl::MakeVariable(uint32_t id,
// `var` declarations will have a resolved type of ref<storage>, but at the // `var` declarations will have a resolved type of ref<storage>, but at the
// AST level both `var` and `let` are declared with the same type. // AST level both `var` and `let` are declared with the same type.
return create<ast::Variable>(Source{}, builder_.Symbols().Register(name), sc, return create<ast::Variable>(Source{}, builder_.Symbols().Register(name), sc,
storage_type->Build(builder_), is_const, access, storage_type->Build(builder_), is_const,
constructor, decorations); constructor, decorations);
} }
@ -1501,7 +1500,7 @@ TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
} }
auto source = GetSourceForInst(inst); auto source = GetSourceForInst(inst);
auto* ast_type = original_ast_type->UnwrapAliasAndAccess(); auto* ast_type = original_ast_type->UnwrapAlias();
// TODO(dneto): Note: NullConstant for int, uint, float map to a regular 0. // TODO(dneto): Note: NullConstant for int, uint, float map to a regular 0.
// So canonicalization should map that way too. // So canonicalization should map that way too.
@ -1577,7 +1576,7 @@ ast::Expression* ParserImpl::MakeNullValue(const Type* type) {
} }
auto* original_type = type; auto* original_type = type;
type = type->UnwrapAliasAndAccess(); type = type->UnwrapAlias();
if (type->Is<Bool>()) { if (type->Is<Bool>()) {
return create<ast::ScalarConstructorExpression>( return create<ast::ScalarConstructorExpression>(
@ -2123,15 +2122,13 @@ const Pointer* ParserImpl::GetTypeForHandleVar(
ast_store_type = ty_.SampledTexture(dim, ast_sampled_component_type); ast_store_type = ty_.SampledTexture(dim, ast_sampled_component_type);
} }
} else { } else {
const auto access = usage.IsStorageReadTexture() const auto access = usage.IsStorageReadTexture() ? ast::Access::kRead
? ast::AccessControl::kRead : ast::Access::kWrite;
: ast::AccessControl::kWrite;
const auto format = enum_converter_.ToImageFormat(image_type->format()); const auto format = enum_converter_.ToImageFormat(image_type->format());
if (format == ast::ImageFormat::kNone) { if (format == ast::ImageFormat::kNone) {
return nullptr; return nullptr;
} }
ast_store_type = ast_store_type = ty_.StorageTexture(dim, format, access);
ty_.AccessControl(ty_.StorageTexture(dim, format), access);
} }
} else { } else {
Fail() << "unsupported: UniformConstant variable is not a recognized " Fail() << "unsupported: UniformConstant variable is not a recognized "

View File

@ -220,6 +220,7 @@ TEST_F(SpvParserTest, EmitFunctions_CalleePrecedesCaller) {
VariableConst{ VariableConst{
leaf_result leaf_result
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{
@ -243,6 +244,7 @@ TEST_F(SpvParserTest, EmitFunctions_CalleePrecedesCaller) {
VariableConst{ VariableConst{
branch_result branch_result
none none
undefined
__u32 __u32
{ {
Call[not set]{ Call[not set]{
@ -307,16 +309,19 @@ TEST_F(SpvParserTest, EmitFunctions_MixedParamTypes) {
VariableConst{ VariableConst{
a a
none none
undefined
__u32 __u32
} }
VariableConst{ VariableConst{
b b
none none
undefined
__f32 __f32
} }
VariableConst{ VariableConst{
c c
none none
undefined
__i32 __i32
} }
) )
@ -347,16 +352,19 @@ TEST_F(SpvParserTest, EmitFunctions_GenerateParamNames) {
VariableConst{ VariableConst{
x_14 x_14
none none
undefined
__u32 __u32
} }
VariableConst{ VariableConst{
x_15 x_15
none none
undefined
__f32 __f32
} }
VariableConst{ VariableConst{
x_16 x_16
none none
undefined
__i32 __i32
} }
) )

File diff suppressed because it is too large Load Diff

View File

@ -196,6 +196,7 @@ TEST_F(SpvModuleScopeVarParserTest, AnonWorkgroupVar) {
Variable{ Variable{
x_52 x_52
workgroup workgroup
undefined
__f32 __f32
})")); })"));
} }
@ -217,6 +218,7 @@ TEST_F(SpvModuleScopeVarParserTest, NamedWorkgroupVar) {
Variable{ Variable{
the_counter the_counter
workgroup workgroup
undefined
__f32 __f32
})")); })"));
} }
@ -238,6 +240,7 @@ TEST_F(SpvModuleScopeVarParserTest, PrivateVar) {
Variable{ Variable{
my_own_private_idaho my_own_private_idaho
private private
undefined
__f32 __f32
})")); })"));
} }
@ -267,6 +270,7 @@ TEST_F(SpvModuleScopeVarParserTest, BuiltinVertexIndex) {
} }
x_52 x_52
in in
undefined
__u32 __u32
})")); })"));
} }
@ -322,6 +326,7 @@ TEST_F(SpvModuleScopeVarParserTest, BuiltinPosition_MapsToModuleScopeVec4Var) {
} }
gl_Position gl_Position
out out
undefined
__vec_4__f32 __vec_4__f32
})")) })"))
<< module_str; << module_str;
@ -547,6 +552,7 @@ TEST_F(SpvModuleScopeVarParserTest, BuiltinPointSize_Write1_IsErased) {
} }
gl_Position gl_Position
out out
undefined
__vec_4__f32 __vec_4__f32
} }
Function main -> __void Function main -> __void
@ -601,6 +607,7 @@ TEST_F(SpvModuleScopeVarParserTest, BuiltinPointSize_ReadReplaced) {
Variable{ Variable{
x_900 x_900
private private
undefined
__f32 __f32
} }
Variable{ Variable{
@ -609,6 +616,7 @@ TEST_F(SpvModuleScopeVarParserTest, BuiltinPointSize_ReadReplaced) {
} }
gl_Position gl_Position
out out
undefined
__vec_4__f32 __vec_4__f32
} }
Function main -> __void Function main -> __void
@ -672,6 +680,7 @@ TEST_F(SpvModuleScopeVarParserTest,
} }
gl_Position gl_Position
out out
undefined
__vec_4__f32 __vec_4__f32
} }
Function main -> __void Function main -> __void
@ -770,6 +779,7 @@ TEST_F(SpvModuleScopeVarParserTest,
Variable{ Variable{
x_900 x_900
private private
undefined
__f32 __f32
} }
Function main -> __void Function main -> __void
@ -961,6 +971,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarInitializers) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_1 x_1
private private
undefined
__bool __bool
{ {
ScalarConstructor[not set]{true} ScalarConstructor[not set]{true}
@ -969,6 +980,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarInitializers) {
Variable{ Variable{
x_2 x_2
private private
undefined
__bool __bool
{ {
ScalarConstructor[not set]{false} ScalarConstructor[not set]{false}
@ -977,6 +989,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarInitializers) {
Variable{ Variable{
x_3 x_3
private private
undefined
__i32 __i32
{ {
ScalarConstructor[not set]{-1} ScalarConstructor[not set]{-1}
@ -985,6 +998,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarInitializers) {
Variable{ Variable{
x_4 x_4
private private
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{1u} ScalarConstructor[not set]{1u}
@ -993,6 +1007,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarInitializers) {
Variable{ Variable{
x_5 x_5
private private
undefined
__f32 __f32
{ {
ScalarConstructor[not set]{1.500000} ScalarConstructor[not set]{1.500000}
@ -1018,6 +1033,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarNullInitializers) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_1 x_1
private private
undefined
__bool __bool
{ {
ScalarConstructor[not set]{false} ScalarConstructor[not set]{false}
@ -1026,6 +1042,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarNullInitializers) {
Variable{ Variable{
x_2 x_2
private private
undefined
__i32 __i32
{ {
ScalarConstructor[not set]{0} ScalarConstructor[not set]{0}
@ -1034,6 +1051,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarNullInitializers) {
Variable{ Variable{
x_3 x_3
private private
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{0u} ScalarConstructor[not set]{0u}
@ -1042,6 +1060,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarNullInitializers) {
Variable{ Variable{
x_4 x_4
private private
undefined
__f32 __f32
{ {
ScalarConstructor[not set]{0.000000} ScalarConstructor[not set]{0.000000}
@ -1067,6 +1086,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarUndefInitializers) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_1 x_1
private private
undefined
__bool __bool
{ {
ScalarConstructor[not set]{false} ScalarConstructor[not set]{false}
@ -1075,6 +1095,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarUndefInitializers) {
Variable{ Variable{
x_2 x_2
private private
undefined
__i32 __i32
{ {
ScalarConstructor[not set]{0} ScalarConstructor[not set]{0}
@ -1083,6 +1104,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarUndefInitializers) {
Variable{ Variable{
x_3 x_3
private private
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{0u} ScalarConstructor[not set]{0u}
@ -1091,6 +1113,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarUndefInitializers) {
Variable{ Variable{
x_4 x_4
private private
undefined
__f32 __f32
{ {
ScalarConstructor[not set]{0.000000} ScalarConstructor[not set]{0.000000}
@ -1114,6 +1137,7 @@ TEST_F(SpvModuleScopeVarParserTest, VectorInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1137,6 +1161,7 @@ TEST_F(SpvModuleScopeVarParserTest, VectorBoolNullInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__vec_2__bool __vec_2__bool
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1160,6 +1185,7 @@ TEST_F(SpvModuleScopeVarParserTest, VectorBoolUndefInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__vec_2__bool __vec_2__bool
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1186,6 +1212,7 @@ TEST_F(SpvModuleScopeVarParserTest, VectorUintNullInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__vec_2__u32 __vec_2__u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1209,6 +1236,7 @@ TEST_F(SpvModuleScopeVarParserTest, VectorUintUndefInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__vec_2__u32 __vec_2__u32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1235,6 +1263,7 @@ TEST_F(SpvModuleScopeVarParserTest, VectorIntNullInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__vec_2__i32 __vec_2__i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1258,6 +1287,7 @@ TEST_F(SpvModuleScopeVarParserTest, VectorIntUndefInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__vec_2__i32 __vec_2__i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1284,6 +1314,7 @@ TEST_F(SpvModuleScopeVarParserTest, VectorFloatNullInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1307,6 +1338,7 @@ TEST_F(SpvModuleScopeVarParserTest, VectorFloatUndefInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__vec_2__f32 __vec_2__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1339,6 +1371,7 @@ TEST_F(SpvModuleScopeVarParserTest, MatrixInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__mat_2_3__f32 __mat_2_3__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1375,6 +1408,7 @@ TEST_F(SpvModuleScopeVarParserTest, MatrixNullInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__mat_2_3__f32 __mat_2_3__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1411,6 +1445,7 @@ TEST_F(SpvModuleScopeVarParserTest, MatrixUndefInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__mat_2_3__f32 __mat_2_3__f32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1451,6 +1486,7 @@ TEST_F(SpvModuleScopeVarParserTest, ArrayInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__array__u32_2 __array__u32_2
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1474,6 +1510,7 @@ TEST_F(SpvModuleScopeVarParserTest, ArrayNullInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__array__u32_2 __array__u32_2
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1497,6 +1534,7 @@ TEST_F(SpvModuleScopeVarParserTest, ArrayUndefInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__array__u32_2 __array__u32_2
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1525,6 +1563,7 @@ TEST_F(SpvModuleScopeVarParserTest, StructInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__type_name_S __type_name_S
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1554,6 +1593,7 @@ TEST_F(SpvModuleScopeVarParserTest, StructNullInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__type_name_S __type_name_S
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1585,6 +1625,7 @@ TEST_F(SpvModuleScopeVarParserTest, StructUndefInitializer) {
EXPECT_THAT(module_str, HasSubstr(R"(Variable{ EXPECT_THAT(module_str, HasSubstr(R"(Variable{
x_200 x_200
private private
undefined
__type_name_S __type_name_S
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -1623,6 +1664,7 @@ TEST_F(SpvModuleScopeVarParserTest, LocationDecoration_Valid) {
} }
myvar myvar
in in
undefined
__u32 __u32
})")) })"))
<< module_str; << module_str;
@ -1674,7 +1716,8 @@ TEST_F(SpvModuleScopeVarParserTest, DescriptorGroupDecoration_Valid) {
} }
x_1 x_1
storage storage
__access_control_read_write__type_name_S read_write
__type_name_S
})")) })"))
<< module_str; << module_str;
} }
@ -1727,7 +1770,8 @@ TEST_F(SpvModuleScopeVarParserTest, BindingDecoration_Valid) {
} }
x_1 x_1
storage storage
__access_control_read_write__type_name_S read_write
__type_name_S
})")) })"))
<< module_str; << module_str;
} }
@ -1784,7 +1828,8 @@ TEST_F(SpvModuleScopeVarParserTest,
Variable{ Variable{
x_1 x_1
storage storage
__access_control_read_write__type_name_S read_write
__type_name_S
} }
)")) << module_str; )")) << module_str;
} }
@ -1817,7 +1862,8 @@ TEST_F(SpvModuleScopeVarParserTest, ColMajorDecoration_Dropped) {
Variable{ Variable{
myvar myvar
storage storage
__access_control_read_write__type_name_S read_write
__type_name_S
} }
})")) << module_str; })")) << module_str;
} }
@ -1849,7 +1895,8 @@ TEST_F(SpvModuleScopeVarParserTest, MatrixStrideDecoration_Dropped) {
Variable{ Variable{
myvar myvar
storage storage
__access_control_read_write__type_name_S read_write
__type_name_S
} }
})")) << module_str; })")) << module_str;
} }
@ -1905,7 +1952,8 @@ TEST_F(SpvModuleScopeVarParserTest, StorageBuffer_NonWritable_AllMembers) {
Variable{ Variable{
x_1 x_1
storage storage
__access_control_read_only__type_name_S read
__type_name_S
} }
})")) << module_str; })")) << module_str;
} }
@ -1937,7 +1985,8 @@ TEST_F(SpvModuleScopeVarParserTest, StorageBuffer_NonWritable_NotAllMembers) {
Variable{ Variable{
x_1 x_1
storage storage
__access_control_read_write__type_name_S read_write
__type_name_S
} }
})")) << module_str; })")) << module_str;
} }
@ -1972,7 +2021,8 @@ TEST_F(
Variable{ Variable{
x_1 x_1
storage storage
__access_control_read_write__type_name_S read_write
__type_name_S
} }
})")) << module_str; })")) << module_str;
} }
@ -1996,6 +2046,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarSpecConstant_DeclareConst_True) {
} }
myconst myconst
none none
undefined
__bool __bool
{ {
ScalarConstructor[not set]{true} ScalarConstructor[not set]{true}
@ -2023,6 +2074,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarSpecConstant_DeclareConst_False) {
} }
myconst myconst
none none
undefined
__bool __bool
{ {
ScalarConstructor[not set]{false} ScalarConstructor[not set]{false}
@ -2050,6 +2102,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarSpecConstant_DeclareConst_U32) {
} }
myconst myconst
none none
undefined
__u32 __u32
{ {
ScalarConstructor[not set]{42u} ScalarConstructor[not set]{42u}
@ -2077,6 +2130,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarSpecConstant_DeclareConst_I32) {
} }
myconst myconst
none none
undefined
__i32 __i32
{ {
ScalarConstructor[not set]{42} ScalarConstructor[not set]{42}
@ -2104,6 +2158,7 @@ TEST_F(SpvModuleScopeVarParserTest, ScalarSpecConstant_DeclareConst_F32) {
} }
myconst myconst
none none
undefined
__f32 __f32
{ {
ScalarConstructor[not set]{2.500000} ScalarConstructor[not set]{2.500000}
@ -2129,6 +2184,7 @@ TEST_F(SpvModuleScopeVarParserTest,
VariableConst{ VariableConst{
myconst myconst
none none
undefined
__f32 __f32
{ {
ScalarConstructor[not set]{2.500000} ScalarConstructor[not set]{2.500000}
@ -2212,6 +2268,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_I32_Load_Direct) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2221,6 +2278,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_I32_Load_Direct) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -2254,6 +2312,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_I32_Load_CopyObject) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2263,6 +2322,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_I32_Load_CopyObject) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -2296,6 +2356,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_I32_Load_AccessChain) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2305,6 +2366,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_I32_Load_AccessChain) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -2363,6 +2425,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_U32_Load_Direct) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2372,6 +2435,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_U32_Load_Direct) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -2402,6 +2466,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_U32_Load_CopyObject) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2411,6 +2476,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_U32_Load_CopyObject) {
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__ptr_in__u32 __ptr_in__u32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -2424,6 +2490,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_U32_Load_CopyObject) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -2457,6 +2524,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_U32_Load_AccessChain) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2466,6 +2534,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_U32_Load_AccessChain) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -2574,6 +2643,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_U32_Direct) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2583,6 +2653,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_U32_Direct) {
VariableConst{ VariableConst{
x_3 x_3
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -2616,6 +2687,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_U32_CopyObject) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2625,6 +2697,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_U32_CopyObject) {
VariableConst{ VariableConst{
x_4 x_4
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -2658,6 +2731,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_U32_AccessChain) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2667,6 +2741,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_U32_AccessChain) {
VariableConst{ VariableConst{
x_4 x_4
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -2699,6 +2774,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_I32_Direct) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2708,6 +2784,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_I32_Direct) {
VariableConst{ VariableConst{
x_3 x_3
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -2744,6 +2821,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_I32_CopyObject) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2753,6 +2831,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_I32_CopyObject) {
VariableConst{ VariableConst{
x_4 x_4
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -2789,6 +2868,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_I32_AccessChain) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -2798,6 +2878,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_In_I32_AccessChain) {
VariableConst{ VariableConst{
x_4 x_4
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -2852,6 +2933,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_Out_U32_Direct) {
} }
x_1 x_1
out out
undefined
__u32 __u32
})")); })"));
@ -2888,6 +2970,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_Out_U32_CopyObject) {
} }
x_1 x_1
out out
undefined
__u32 __u32
})")); })"));
@ -2924,6 +3007,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_Out_U32_AccessChain) {
} }
x_1 x_1
out out
undefined
__u32 __u32
})")); })"));
@ -2959,6 +3043,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_Out_I32_Direct) {
} }
x_1 x_1
out out
undefined
__u32 __u32
})")); })"));
@ -3001,6 +3086,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_Out_I32_CopyObject) {
} }
x_1 x_1
out out
undefined
__u32 __u32
})")); })"));
@ -3043,6 +3129,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleMask_Out_I32_AccessChain) {
} }
x_1 x_1
out out
undefined
__u32 __u32
})")); })"));
@ -3100,6 +3187,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_Direct) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3109,6 +3197,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_Direct) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -3142,6 +3231,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_CopyObject) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3151,6 +3241,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_CopyObject) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -3184,6 +3275,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_AccessChain) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3193,6 +3285,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_AccessChain) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -3251,6 +3344,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_Direct) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3260,6 +3354,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_Direct) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -3290,6 +3385,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_CopyObject) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3299,6 +3395,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_CopyObject) {
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__ptr_in__u32 __ptr_in__u32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -3312,6 +3409,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_CopyObject) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -3345,6 +3443,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_AccessChain) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3354,6 +3453,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_AccessChain) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -3427,6 +3527,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_Direct) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3436,6 +3537,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_Direct) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -3469,6 +3571,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_CopyObject) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3478,6 +3581,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_CopyObject) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -3511,6 +3615,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_AccessChain) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3520,6 +3625,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_AccessChain) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__i32 __i32
{ {
TypeConstructor[not set]{ TypeConstructor[not set]{
@ -3576,6 +3682,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_Direct) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3585,6 +3692,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_Direct) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -3615,6 +3723,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_CopyObject) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3624,6 +3733,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_CopyObject) {
VariableConst{ VariableConst{
x_11 x_11
none none
undefined
__ptr_in__u32 __ptr_in__u32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -3637,6 +3747,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_CopyObject) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
UnaryOp[not set]{ UnaryOp[not set]{
@ -3670,6 +3781,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_AccessChain) {
} }
x_1 x_1
in in
undefined
__u32 __u32
})")); })"));
@ -3679,6 +3791,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_AccessChain) {
VariableConst{ VariableConst{
x_2 x_2
none none
undefined
__u32 __u32
{ {
Identifier[not set]{x_1} Identifier[not set]{x_1}
@ -3832,6 +3945,7 @@ TEST_F(SpvModuleScopeVarParserTest, InputVarsConvertedToPrivate) {
R"(Variable{ R"(Variable{
x_1 x_1
private private
undefined
__u32 __u32
} }
)"; )";
@ -3856,6 +3970,7 @@ TEST_F(SpvModuleScopeVarParserTest, OutputVarsConvertedToPrivate) {
R"(Variable{ R"(Variable{
x_1 x_1
private private
undefined
__u32 __u32
} }
)"; )";
@ -3903,21 +4018,25 @@ TEST_F(SpvModuleScopeVarParserTest, EntryPointWrapping_IOLocations) {
Variable{ Variable{
x_1 x_1
private private
undefined
__u32 __u32
} }
Variable{ Variable{
x_2 x_2
private private
undefined
__u32 __u32
} }
Variable{ Variable{
x_3 x_3
private private
undefined
__u32 __u32
} }
Variable{ Variable{
x_4 x_4
private private
undefined
__u32 __u32
} }
Function main_1 -> __void Function main_1 -> __void
@ -3934,6 +4053,7 @@ TEST_F(SpvModuleScopeVarParserTest, EntryPointWrapping_IOLocations) {
} }
x_1_param x_1_param
none none
undefined
__u32 __u32
} }
VariableConst{ VariableConst{
@ -3942,6 +4062,7 @@ TEST_F(SpvModuleScopeVarParserTest, EntryPointWrapping_IOLocations) {
} }
x_3_param x_3_param
none none
undefined
__u32 __u32
} }
) )

View File

@ -33,7 +33,6 @@ TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Reference);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Vector); TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Vector);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Matrix); TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Matrix);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Array); TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Array);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::AccessControl);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Sampler); TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Sampler);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Texture); TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Texture);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::DepthTexture); TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::DepthTexture);
@ -79,12 +78,6 @@ struct ArrayHasher {
} }
}; };
struct AccessControlHasher {
size_t operator()(const AccessControl& t) const {
return utils::Hash(t.type, t.access);
}
};
struct MultisampledTextureHasher { struct MultisampledTextureHasher {
size_t operator()(const MultisampledTexture& t) const { size_t operator()(const MultisampledTexture& t) const {
return utils::Hash(t.dims, t.type); return utils::Hash(t.dims, t.type);
@ -99,7 +92,7 @@ struct SampledTextureHasher {
struct StorageTextureHasher { struct StorageTextureHasher {
size_t operator()(const StorageTexture& t) const { size_t operator()(const StorageTexture& t) const {
return utils::Hash(t.dims, t.format); return utils::Hash(t.dims, t.format, t.access);
} }
}; };
} // namespace } // namespace
@ -124,10 +117,6 @@ static bool operator==(const Array& a, const Array& b) {
return a.type == b.type && a.size == b.size && a.stride == b.stride; return a.type == b.type && a.size == b.size && a.stride == b.stride;
} }
static bool operator==(const AccessControl& a, const AccessControl& b) {
return a.type == b.type && a.access == b.access;
}
static bool operator==(const MultisampledTexture& a, static bool operator==(const MultisampledTexture& a,
const MultisampledTexture& b) { const MultisampledTexture& b) {
return a.dims == b.dims && a.type == b.type; return a.dims == b.dims && a.type == b.type;
@ -200,14 +189,6 @@ ast::Type* Array::Build(ProgramBuilder& b) const {
return b.ty.array(type->Build(b), size, stride); return b.ty.array(type->Build(b), size, stride);
} }
AccessControl::AccessControl(const Type* t, ast::AccessControl::Access a)
: type(t), access(a) {}
AccessControl::AccessControl(const AccessControl&) = default;
ast::Type* AccessControl::Build(ProgramBuilder& b) const {
return b.ty.access(access, type->Build(b));
}
Sampler::Sampler(ast::SamplerKind k) : kind(k) {} Sampler::Sampler(ast::SamplerKind k) : kind(k) {}
Sampler::Sampler(const Sampler&) = default; Sampler::Sampler(const Sampler&) = default;
@ -241,12 +222,14 @@ ast::Type* SampledTexture::Build(ProgramBuilder& b) const {
return b.ty.sampled_texture(dims, type->Build(b)); return b.ty.sampled_texture(dims, type->Build(b));
} }
StorageTexture::StorageTexture(ast::TextureDimension d, ast::ImageFormat f) StorageTexture::StorageTexture(ast::TextureDimension d,
: Base(d), format(f) {} ast::ImageFormat f,
ast::Access a)
: Base(d), format(f), access(a) {}
StorageTexture::StorageTexture(const StorageTexture&) = default; StorageTexture::StorageTexture(const StorageTexture&) = default;
ast::Type* StorageTexture::Build(ProgramBuilder& b) const { ast::Type* StorageTexture::Build(ProgramBuilder& b) const {
return b.ty.storage_texture(dims, format); return b.ty.storage_texture(dims, format, access);
} }
Named::Named(Symbol n) : name(n) {} Named::Named(Symbol n) : name(n) {}
@ -296,11 +279,6 @@ struct TypeManager::State {
matrices_; matrices_;
/// Map of Array to the returned Array type instance /// Map of Array to the returned Array type instance
std::unordered_map<spirv::Array, const spirv::Array*, ArrayHasher> arrays_; std::unordered_map<spirv::Array, const spirv::Array*, ArrayHasher> arrays_;
/// Map of AccessControl to the returned AccessControl type instance
std::unordered_map<spirv::AccessControl,
const spirv::AccessControl*,
AccessControlHasher>
access_controls_;
/// Map of type name to returned Alias instance /// Map of type name to returned Alias instance
std::unordered_map<Symbol, const spirv::Alias*> aliases_; std::unordered_map<Symbol, const spirv::Alias*> aliases_;
/// Map of type name to returned Struct instance /// Map of type name to returned Struct instance
@ -352,27 +330,11 @@ const Type* Type::UnwrapAlias() const {
return type; return type;
} }
const Type* Type::UnwrapAliasAndAccess() const {
auto* type = this;
while (true) {
if (auto* alias = type->As<Alias>()) {
type = alias->type;
} else if (auto* access = type->As<AccessControl>()) {
type = access->type;
} else {
break;
}
}
return type;
}
const Type* Type::UnwrapAll() const { const Type* Type::UnwrapAll() const {
auto* type = this; auto* type = this;
while (true) { while (true) {
if (auto* alias = type->As<Alias>()) { if (auto* alias = type->As<Alias>()) {
type = alias->type; type = alias->type;
} else if (auto* access = type->As<AccessControl>()) {
type = access->type;
} else if (auto* ptr = type->As<Pointer>()) { } else if (auto* ptr = type->As<Pointer>()) {
type = ptr->type; type = ptr->type;
} else { } else {
@ -500,14 +462,6 @@ const spirv::Array* TypeManager::Array(const Type* el,
[&] { return state->allocator_.Create<spirv::Array>(el, size, stride); }); [&] { return state->allocator_.Create<spirv::Array>(el, size, stride); });
} }
const spirv::AccessControl* TypeManager::AccessControl(
const Type* ty,
ast::AccessControl::Access ac) {
return utils::GetOrCreate(
state->access_controls_, spirv::AccessControl(ty, ac),
[&] { return state->allocator_.Create<spirv::AccessControl>(ty, ac); });
}
const spirv::Alias* TypeManager::Alias(Symbol name, const Type* ty) { const spirv::Alias* TypeManager::Alias(Symbol name, const Type* ty) {
return utils::GetOrCreate(state->aliases_, name, [&] { return utils::GetOrCreate(state->aliases_, name, [&] {
return state->allocator_.Create<spirv::Alias>(name, ty); return state->allocator_.Create<spirv::Alias>(name, ty);
@ -553,10 +507,12 @@ const spirv::SampledTexture* TypeManager::SampledTexture(
const spirv::StorageTexture* TypeManager::StorageTexture( const spirv::StorageTexture* TypeManager::StorageTexture(
ast::TextureDimension dims, ast::TextureDimension dims,
ast::ImageFormat fmt) { ast::ImageFormat fmt,
ast::Access access) {
return utils::GetOrCreate( return utils::GetOrCreate(
state->storage_textures_, spirv::StorageTexture(dims, fmt), [&] { state->storage_textures_, spirv::StorageTexture(dims, fmt, access), [&] {
return state->allocator_.Create<spirv::StorageTexture>(dims, fmt); return state->allocator_.Create<spirv::StorageTexture>(dims, fmt,
access);
}); });
} }
@ -614,12 +570,6 @@ std::string Array::String() const {
return ss.str(); return ss.str();
} }
std::string AccessControl::String() const {
std::stringstream ss;
ss << "[[access(" << access << ")]] " << type->String();
return ss.str();
}
std::string Sampler::String() const { std::string Sampler::String() const {
switch (kind) { switch (kind) {
case ast::SamplerKind::kSampler: case ast::SamplerKind::kSampler:
@ -650,7 +600,7 @@ std::string SampledTexture::String() const {
std::string StorageTexture::String() const { std::string StorageTexture::String() const {
std::stringstream ss; std::stringstream ss;
ss << "texture_storage_" << dims << "<" << format << ">"; ss << "texture_storage_" << dims << "<" << format << ", " << access << ">";
return ss.str(); return ss.str();
} }

View File

@ -19,7 +19,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "src/ast/access_control.h" #include "src/ast/access.h"
#include "src/ast/sampler.h" #include "src/ast/sampler.h"
#include "src/ast/storage_class.h" #include "src/ast/storage_class.h"
#include "src/ast/storage_texture.h" #include "src/ast/storage_texture.h"
@ -56,9 +56,6 @@ class Type : public Castable<Type> {
/// @returns the inner most aliased type if this is an alias, `this` otherwise /// @returns the inner most aliased type if this is an alias, `this` otherwise
const Type* UnwrapAlias() const; const Type* UnwrapAlias() const;
/// @returns the type with all aliasing and access control removed
const Type* UnwrapAliasAndAccess() const;
/// @returns the type with all aliasing, access control and pointers removed /// @returns the type with all aliasing, access control and pointers removed
const Type* UnwrapAll() const; const Type* UnwrapAll() const;
@ -290,33 +287,6 @@ struct Array : public Castable<Array, Type> {
uint32_t const stride; uint32_t const stride;
}; };
/// `[[access]]` type
struct AccessControl : public Castable<AccessControl, Type> {
/// Constructor
/// @param ty the inner type
/// @param ac the access control
AccessControl(const Type* ty, ast::AccessControl::Access ac);
/// Copy constructor
/// @param other the other type to copy
AccessControl(const AccessControl& other);
/// @return the
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
ast::Type* Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
std::string String() const override;
#endif // NDEBUG
/// the inner type
Type const* const type;
/// the access control
ast::AccessControl::Access const access;
};
/// `sampler` type /// `sampler` type
struct Sampler : public Castable<Sampler, Type> { struct Sampler : public Castable<Sampler, Type> {
/// Constructor /// Constructor
@ -427,7 +397,8 @@ struct StorageTexture : public Castable<StorageTexture, Texture> {
/// Constructor /// Constructor
/// @param d the texture dimensions /// @param d the texture dimensions
/// @param f the storage image format /// @param f the storage image format
StorageTexture(ast::TextureDimension d, ast::ImageFormat f); /// @param a the access control
StorageTexture(ast::TextureDimension d, ast::ImageFormat f, ast::Access a);
/// Copy constructor /// Copy constructor
/// @param other the other type to copy /// @param other the other type to copy
@ -444,6 +415,9 @@ struct StorageTexture : public Castable<StorageTexture, Texture> {
/// the storage image format /// the storage image format
ast::ImageFormat const format; ast::ImageFormat const format;
/// the access control
ast::Access const access;
}; };
/// Base class for named types /// Base class for named types
@ -556,12 +530,6 @@ class TypeManager {
/// @return a Array type. Repeated calls with the same arguments will return /// @return a Array type. Repeated calls with the same arguments will return
/// the same pointer. /// the same pointer.
const spirv::Array* Array(const Type* el, uint32_t sz, uint32_t st); const spirv::Array* Array(const Type* el, uint32_t sz, uint32_t st);
/// @param ty the inner type
/// @param ac the access control
/// @return a AccessControl type. Repeated calls with the same arguments will
/// return the same pointer.
const spirv::AccessControl* AccessControl(const Type* ty,
ast::AccessControl::Access ac);
/// @param n the alias name /// @param n the alias name
/// @param t the aliased type /// @param t the aliased type
/// @return a Alias type. Repeated calls with the same arguments will return /// @return a Alias type. Repeated calls with the same arguments will return
@ -594,10 +562,12 @@ class TypeManager {
const Type* t); const Type* t);
/// @param d the texture dimensions /// @param d the texture dimensions
/// @param f the storage image format /// @param f the storage image format
/// @param a the access control
/// @return a StorageTexture type. Repeated calls with the same arguments will /// @return a StorageTexture type. Repeated calls with the same arguments will
/// return the same pointer. /// return the same pointer.
const spirv::StorageTexture* StorageTexture(ast::TextureDimension d, const spirv::StorageTexture* StorageTexture(ast::TextureDimension d,
ast::ImageFormat f); ast::ImageFormat f,
ast::Access a);
private: private:
struct State; struct State;

View File

@ -35,8 +35,6 @@ TEST(SpvParserTypeTest, SameArgumentsGivesSamePointer) {
EXPECT_EQ(ty.Vector(ty.I32(), 3), ty.Vector(ty.I32(), 3)); EXPECT_EQ(ty.Vector(ty.I32(), 3), ty.Vector(ty.I32(), 3));
EXPECT_EQ(ty.Matrix(ty.I32(), 3, 2), ty.Matrix(ty.I32(), 3, 2)); EXPECT_EQ(ty.Matrix(ty.I32(), 3, 2), ty.Matrix(ty.I32(), 3, 2));
EXPECT_EQ(ty.Array(ty.I32(), 3, 2), ty.Array(ty.I32(), 3, 2)); EXPECT_EQ(ty.Array(ty.I32(), 3, 2), ty.Array(ty.I32(), 3, 2));
EXPECT_EQ(ty.AccessControl(ty.I32(), ast::AccessControl::kRead),
ty.AccessControl(ty.I32(), ast::AccessControl::kRead));
EXPECT_EQ(ty.Alias(sym, ty.I32()), ty.Alias(sym, ty.I32())); EXPECT_EQ(ty.Alias(sym, ty.I32()), ty.Alias(sym, ty.I32()));
EXPECT_EQ(ty.Struct(sym, {ty.I32()}), ty.Struct(sym, {ty.I32()})); EXPECT_EQ(ty.Struct(sym, {ty.I32()}), ty.Struct(sym, {ty.I32()}));
EXPECT_EQ(ty.Sampler(ast::SamplerKind::kSampler), EXPECT_EQ(ty.Sampler(ast::SamplerKind::kSampler),
@ -47,10 +45,10 @@ TEST(SpvParserTypeTest, SameArgumentsGivesSamePointer) {
ty.MultisampledTexture(ast::TextureDimension::k2d, ty.I32())); ty.MultisampledTexture(ast::TextureDimension::k2d, ty.I32()));
EXPECT_EQ(ty.SampledTexture(ast::TextureDimension::k2d, ty.I32()), EXPECT_EQ(ty.SampledTexture(ast::TextureDimension::k2d, ty.I32()),
ty.SampledTexture(ast::TextureDimension::k2d, ty.I32())); ty.SampledTexture(ast::TextureDimension::k2d, ty.I32()));
EXPECT_EQ( EXPECT_EQ(ty.StorageTexture(ast::TextureDimension::k2d,
ty.StorageTexture(ast::TextureDimension::k2d, ast::ImageFormat::kR16Sint), ast::ImageFormat::kR16Sint, ast::Access::kRead),
ty.StorageTexture(ast::TextureDimension::k2d, ty.StorageTexture(ast::TextureDimension::k2d,
ast::ImageFormat::kR16Sint)); ast::ImageFormat::kR16Sint, ast::Access::kRead));
} }
TEST(SpvParserTypeTest, DifferentArgumentsGivesDifferentPointer) { TEST(SpvParserTypeTest, DifferentArgumentsGivesDifferentPointer) {
@ -70,10 +68,6 @@ TEST(SpvParserTypeTest, DifferentArgumentsGivesDifferentPointer) {
EXPECT_NE(ty.Array(ty.I32(), 3, 2), ty.Array(ty.U32(), 3, 2)); EXPECT_NE(ty.Array(ty.I32(), 3, 2), ty.Array(ty.U32(), 3, 2));
EXPECT_NE(ty.Array(ty.I32(), 3, 2), ty.Array(ty.I32(), 2, 2)); EXPECT_NE(ty.Array(ty.I32(), 3, 2), ty.Array(ty.I32(), 2, 2));
EXPECT_NE(ty.Array(ty.I32(), 3, 2), ty.Array(ty.I32(), 3, 3)); EXPECT_NE(ty.Array(ty.I32(), 3, 2), ty.Array(ty.I32(), 3, 3));
EXPECT_NE(ty.AccessControl(ty.I32(), ast::AccessControl::kRead),
ty.AccessControl(ty.U32(), ast::AccessControl::kRead));
EXPECT_NE(ty.AccessControl(ty.I32(), ast::AccessControl::kRead),
ty.AccessControl(ty.I32(), ast::AccessControl::kWrite));
EXPECT_NE(ty.Alias(sym_a, ty.I32()), ty.Alias(sym_b, ty.I32())); EXPECT_NE(ty.Alias(sym_a, ty.I32()), ty.Alias(sym_b, ty.I32()));
EXPECT_NE(ty.Struct(sym_a, {ty.I32()}), ty.Struct(sym_b, {ty.I32()})); EXPECT_NE(ty.Struct(sym_a, {ty.I32()}), ty.Struct(sym_b, {ty.I32()}));
EXPECT_NE(ty.Sampler(ast::SamplerKind::kSampler), EXPECT_NE(ty.Sampler(ast::SamplerKind::kSampler),
@ -88,14 +82,18 @@ TEST(SpvParserTypeTest, DifferentArgumentsGivesDifferentPointer) {
ty.SampledTexture(ast::TextureDimension::k3d, ty.I32())); ty.SampledTexture(ast::TextureDimension::k3d, ty.I32()));
EXPECT_NE(ty.SampledTexture(ast::TextureDimension::k2d, ty.I32()), EXPECT_NE(ty.SampledTexture(ast::TextureDimension::k2d, ty.I32()),
ty.SampledTexture(ast::TextureDimension::k2d, ty.U32())); ty.SampledTexture(ast::TextureDimension::k2d, ty.U32()));
EXPECT_NE( EXPECT_NE(ty.StorageTexture(ast::TextureDimension::k2d,
ty.StorageTexture(ast::TextureDimension::k2d, ast::ImageFormat::kR16Sint), ast::ImageFormat::kR16Sint, ast::Access::kRead),
ty.StorageTexture(ast::TextureDimension::k3d, ty.StorageTexture(ast::TextureDimension::k3d,
ast::ImageFormat::kR16Sint)); ast::ImageFormat::kR16Sint, ast::Access::kRead));
EXPECT_NE( EXPECT_NE(ty.StorageTexture(ast::TextureDimension::k2d,
ty.StorageTexture(ast::TextureDimension::k2d, ast::ImageFormat::kR16Sint), ast::ImageFormat::kR16Sint, ast::Access::kRead),
ty.StorageTexture(ast::TextureDimension::k2d, ty.StorageTexture(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Sint)); ast::ImageFormat::kR32Sint, ast::Access::kRead));
EXPECT_NE(ty.StorageTexture(ast::TextureDimension::k2d,
ast::ImageFormat::kR16Sint, ast::Access::kRead),
ty.StorageTexture(ast::TextureDimension::k2d,
ast::ImageFormat::kR16Sint, ast::Access::kWrite));
} }
} // namespace } // namespace

View File

@ -66,9 +66,9 @@ const char kVertexStage[] = "vertex";
const char kFragmentStage[] = "fragment"; const char kFragmentStage[] = "fragment";
const char kComputeStage[] = "compute"; const char kComputeStage[] = "compute";
const char kReadAccessControl[] = "read"; const char kReadAccess[] = "read";
const char kWriteAccessControl[] = "write"; const char kWriteAccess[] = "write";
const char kReadWriteAccessControl[] = "read_write"; const char kReadWriteAccess[] = "read_write";
ast::Builtin ident_to_builtin(const std::string& str) { ast::Builtin ident_to_builtin(const std::string& str) {
if (str == "position") { if (str == "position") {
@ -204,9 +204,13 @@ ParserImpl::TypedIdentifier::TypedIdentifier() = default;
ParserImpl::TypedIdentifier::TypedIdentifier(const TypedIdentifier&) = default; ParserImpl::TypedIdentifier::TypedIdentifier(const TypedIdentifier&) = default;
ParserImpl::TypedIdentifier::TypedIdentifier(ast::Type* type_in, ParserImpl::TypedIdentifier::TypedIdentifier(ast::Type* type_in,
ast::Access access_in,
std::string name_in, std::string name_in,
Source source_in) Source source_in)
: type(type_in), name(std::move(name_in)), source(std::move(source_in)) {} : type(type_in),
access(access_in),
name(std::move(name_in)),
source(std::move(source_in)) {}
ParserImpl::TypedIdentifier::~TypedIdentifier() = default; ParserImpl::TypedIdentifier::~TypedIdentifier() = default;
@ -237,10 +241,12 @@ ParserImpl::VarDeclInfo::VarDeclInfo(const VarDeclInfo&) = default;
ParserImpl::VarDeclInfo::VarDeclInfo(Source source_in, ParserImpl::VarDeclInfo::VarDeclInfo(Source source_in,
std::string name_in, std::string name_in,
ast::StorageClass storage_class_in, ast::StorageClass storage_class_in,
ast::Access access_in,
ast::Type* type_in) ast::Type* type_in)
: source(std::move(source_in)), : source(std::move(source_in)),
name(std::move(name_in)), name(std::move(name_in)),
storage_class(storage_class_in), storage_class(storage_class_in),
access(access_in),
type(type_in) {} type(type_in) {}
ParserImpl::VarDeclInfo::~VarDeclInfo() = default; ParserImpl::VarDeclInfo::~VarDeclInfo() = default;
@ -477,7 +483,8 @@ Maybe<ast::Variable*> ParserImpl::global_variable_decl(
return create<ast::Variable>( return create<ast::Variable>(
decl->source, // source decl->source, // source
builder_.Symbols().Register(decl->name), // symbol builder_.Symbols().Register(decl->name), // symbol
decl->storage_class, // storage_class decl->storage_class, // storage class
decl->access, // access control
decl->type, // type decl->type, // type
false, // is_const false, // is_const
constructor, // constructor constructor, // constructor
@ -511,7 +518,8 @@ Maybe<ast::Variable*> ParserImpl::global_constant_decl(
return create<ast::Variable>( return create<ast::Variable>(
decl->source, // source decl->source, // source
builder_.Symbols().Register(decl->name), // symbol builder_.Symbols().Register(decl->name), // symbol
ast::StorageClass::kNone, // storage_class ast::StorageClass::kNone, // storage class
ast::Access::kUndefined, // access control
decl->type, // type decl->type, // type
true, // is_const true, // is_const
initializer, // constructor initializer, // constructor
@ -519,26 +527,27 @@ Maybe<ast::Variable*> ParserImpl::global_constant_decl(
} }
// variable_decl // variable_decl
// : VAR variable_storage_decoration? variable_ident_decl // : VAR variable_qualifier? variable_ident_decl
Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl(bool allow_inferred) { Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl(bool allow_inferred) {
if (!match(Token::Type::kVar)) Source source;
if (!match(Token::Type::kVar, &source))
return Failure::kNoMatch; return Failure::kNoMatch;
ast::StorageClass sc = ast::StorageClass::kNone; VariableQualifier vq;
auto explicit_sc = variable_storage_decoration(); auto explicit_vq = variable_qualifier();
if (explicit_sc.errored) if (explicit_vq.errored)
return Failure::kErrored; return Failure::kErrored;
if (explicit_sc.matched) { if (explicit_vq.matched) {
sc = explicit_sc.value; vq = explicit_vq.value;
// TODO(crbug.com/tint/697): Remove this. // TODO(crbug.com/tint/697): Remove this.
if (sc == ast::StorageClass::kInput) { if (vq.storage_class == ast::StorageClass::kInput) {
deprecated(explicit_sc.source, deprecated(explicit_vq.source,
"use an entry point parameter instead of a variable in the " "use an entry point parameter instead of a variable in the "
"`in` storage class"); "`in` storage class");
} }
if (sc == ast::StorageClass::kOutput) { if (vq.storage_class == ast::StorageClass::kOutput) {
deprecated(explicit_sc.source, deprecated(explicit_vq.source,
"use an entry point return value instead of a variable in the " "use an entry point return value instead of a variable in the "
"`out` storage class"); "`out` storage class");
} }
@ -549,7 +558,20 @@ Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl(bool allow_inferred) {
if (decl.errored) if (decl.errored)
return Failure::kErrored; return Failure::kErrored;
return VarDeclInfo{decl->source, decl->name, sc, decl->type}; auto access = vq.access;
if (access == ast::Access::kUndefined &&
decl->access != ast::Access::kUndefined) {
// TODO(crbug.com/tint/846): Remove this
access = decl->access;
std::stringstream msg;
msg << "declare access with var<" << vq.storage_class << ", " << access
<< "> instead of using [[access]] decoration";
deprecated(source, msg.str());
}
return VarDeclInfo{decl->source, decl->name, vq.storage_class, access,
decl->type};
} }
// texture_sampler_types // texture_sampler_types
@ -559,7 +581,8 @@ Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl(bool allow_inferred) {
// | multisampled_texture_type LESS_THAN type_decl GREATER_THAN // | multisampled_texture_type LESS_THAN type_decl GREATER_THAN
// | storage_texture_type LESS_THAN image_storage_type // | storage_texture_type LESS_THAN image_storage_type
// COMMA access GREATER_THAN // COMMA access GREATER_THAN
Maybe<ast::Type*> ParserImpl::texture_sampler_types() { Maybe<ast::Type*> ParserImpl::texture_sampler_types(
ast::DecorationList& decos) {
auto type = sampler_type(); auto type = sampler_type();
if (type.matched) if (type.matched)
return type; return type;
@ -601,7 +624,7 @@ Maybe<ast::Type*> ParserImpl::texture_sampler_types() {
if (storage.matched) { if (storage.matched) {
const char* use = "storage texture type"; const char* use = "storage texture type";
using StorageTextureInfo = using StorageTextureInfo =
std::pair<tint::ast::ImageFormat, tint::ast::AccessControl::Access>; std::pair<tint::ast::ImageFormat, tint::ast::Access>;
auto params = expect_lt_gt_block(use, [&]() -> Expect<StorageTextureInfo> { auto params = expect_lt_gt_block(use, [&]() -> Expect<StorageTextureInfo> {
auto format = expect_image_storage_type(use); auto format = expect_image_storage_type(use);
if (format.errored) { if (format.errored) {
@ -609,14 +632,23 @@ Maybe<ast::Type*> ParserImpl::texture_sampler_types() {
} }
if (!match(Token::Type::kComma)) { if (!match(Token::Type::kComma)) {
// TODO(crbug.com/tint/846): Remove this, along with the decos parameter
auto access_decos = take_decorations<ast::AccessDecoration>(decos);
if (access_decos.size() > 1) {
return add_error(access_decos[1]->source(),
"multiple access decorations not allowed");
}
if (access_decos.size() == 0) {
return add_error(source_range, "expected access control");
}
deprecated( deprecated(
peek().source(), peek().source(),
"access control is expected as last parameter of storage textures"); "access control is expected as last parameter of storage textures");
return std::make_pair(format.value, return std::make_pair(format.value, access_decos[0]->value());
tint::ast::AccessControl::kReadWrite);
} }
auto access = expect_access_type(); auto access = expect_access("access control");
if (access.errored) { if (access.errored) {
return Failure::kErrored; return Failure::kErrored;
} }
@ -628,19 +660,8 @@ Maybe<ast::Type*> ParserImpl::texture_sampler_types() {
return Failure::kErrored; return Failure::kErrored;
} }
ast::Type* ty = return builder_.ty.storage_texture(source_range, storage.value,
builder_.ty.storage_texture(source_range, storage.value, params->first); params->first, params->second);
if (params->second != tint::ast::AccessControl::kReadWrite) {
// TODO(crbug.com/tint/846): The ast::AccessControl decoration is
// deprecated, but while we're migrating existing WGSL over to the new
// style of having the access part of the storage texture, we need to
// support both old and new styles. For now, have the new syntax emulate
// the old style AST.
ty = builder_.ty.access(params->second, ty);
}
return ty;
} }
return Failure::kNoMatch; return Failure::kNoMatch;
@ -906,7 +927,8 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
return Failure::kErrored; return Failure::kErrored;
if (allow_inferred && !peek().Is(Token::Type::kColon)) { if (allow_inferred && !peek().Is(Token::Type::kColon)) {
return TypedIdentifier{nullptr, ident.value, ident.source}; return TypedIdentifier{nullptr, ast::Access::kUndefined, ident.value,
ident.source};
} }
if (!expect(use, Token::Type::kColon)) if (!expect(use, Token::Type::kColon))
@ -916,8 +938,6 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
if (decos.errored) if (decos.errored)
return Failure::kErrored; return Failure::kErrored;
auto access_decos = take_decorations<ast::AccessDecoration>(decos.value);
auto t = peek(); auto t = peek();
auto type = type_decl(decos.value); auto type = type_decl(decos.value);
if (type.errored) if (type.errored)
@ -925,52 +945,65 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
if (!type.matched) if (!type.matched)
return add_error(t.source(), "invalid type", use); return add_error(t.source(), "invalid type", use);
auto access_decos = take_decorations<ast::AccessDecoration>(decos.value);
if (!expect_decorations_consumed(decos.value)) if (!expect_decorations_consumed(decos.value))
return Failure::kErrored; return Failure::kErrored;
if (access_decos.size() > 1) if (access_decos.size() > 1)
return add_error(ident.source, "multiple access decorations not allowed"); return add_error(ident.source, "multiple access decorations not allowed");
ast::Type* ty = type.value; auto access =
access_decos.empty() ? ast::Access::kUndefined : access_decos[0]->value();
for (auto* deco : access_decos) { return TypedIdentifier{type.value, access, ident.value, ident.source};
// If we have an access control decoration then we take it and wrap our
// type up with that decoration
ty = builder_.ty.access(deco->source(),
deco->As<ast::AccessDecoration>()->value(), ty);
}
return TypedIdentifier{ty, ident.value, ident.source};
} }
Expect<ast::AccessControl::Access> ParserImpl::expect_access_type() { Expect<ast::Access> ParserImpl::expect_access(const std::string& use) {
auto ident = expect_ident("access_type"); auto ident = expect_ident(use);
if (ident.errored) if (ident.errored)
return Failure::kErrored; return Failure::kErrored;
if (ident.value == kReadAccessControl) if (ident.value == kReadAccess)
return {ast::AccessControl::kRead, ident.source}; return {ast::Access::kRead, ident.source};
if (ident.value == kWriteAccessControl) if (ident.value == kWriteAccess)
return {ast::AccessControl::kWrite, ident.source}; return {ast::Access::kWrite, ident.source};
if (ident.value == kReadWriteAccessControl) if (ident.value == kReadWriteAccess)
return {ast::AccessControl::kReadWrite, ident.source}; return {ast::Access::kReadWrite, ident.source};
return add_error(ident.source, "invalid value for access decoration"); return add_error(ident.source, "invalid value for access decoration");
} }
// variable_storage_decoration // variable_qualifier
// : LESS_THAN storage_class GREATER_THAN // : LESS_THAN storage_class (COMMA access_mode)? GREATER_THAN
Maybe<ast::StorageClass> ParserImpl::variable_storage_decoration() { Maybe<ParserImpl::VariableQualifier> ParserImpl::variable_qualifier() {
if (!peek().IsLessThan()) if (!peek().IsLessThan()) {
return Failure::kNoMatch; return Failure::kNoMatch;
}
const char* use = "variable decoration"; auto* use = "variable declaration";
auto vq = expect_lt_gt_block(use, [&]() -> Expect<VariableQualifier> {
auto source = make_source_range();
auto sc = expect_storage_class(use);
if (sc.errored) {
return Failure::kErrored;
}
if (match(Token::Type::kComma)) {
auto ac = expect_access(use);
if (ac.errored) {
return Failure::kErrored;
}
return VariableQualifier{sc.value, ac.value};
}
return Expect<VariableQualifier>{
VariableQualifier{sc.value, ast::Access::kUndefined}, source};
});
auto sc = expect_lt_gt_block(use, [&] { return expect_storage_class(use); }); if (vq.errored) {
if (sc.errored)
return Failure::kErrored; return Failure::kErrored;
}
return sc; return vq;
} }
// type_alias // type_alias
@ -1088,7 +1121,7 @@ Maybe<ast::Type*> ParserImpl::type_decl(ast::DecorationList& decos) {
return expect_type_decl_matrix(t); return expect_type_decl_matrix(t);
} }
auto texture_or_sampler = texture_sampler_types(); auto texture_or_sampler = texture_sampler_types(decos);
if (texture_or_sampler.errored) if (texture_or_sampler.errored)
return Failure::kErrored; return Failure::kErrored;
if (texture_or_sampler.matched) if (texture_or_sampler.matched)
@ -1449,7 +1482,8 @@ Expect<ast::Variable*> ParserImpl::expect_param() {
auto* var = auto* var =
create<ast::Variable>(decl->source, // source create<ast::Variable>(decl->source, // source
builder_.Symbols().Register(decl->name), // symbol builder_.Symbols().Register(decl->name), // symbol
ast::StorageClass::kNone, // storage_class ast::StorageClass::kNone, // storage class
ast::Access::kUndefined, // access control
decl->type, // type decl->type, // type
true, // is_const true, // is_const
nullptr, // constructor nullptr, // constructor
@ -1712,7 +1746,8 @@ Maybe<ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
auto* var = create<ast::Variable>( auto* var = create<ast::Variable>(
decl->source, // source decl->source, // source
builder_.Symbols().Register(decl->name), // symbol builder_.Symbols().Register(decl->name), // symbol
ast::StorageClass::kNone, // storage_class ast::StorageClass::kNone, // storage class
ast::Access::kUndefined, // access control
decl->type, // type decl->type, // type
true, // is_const true, // is_const
constructor.value, // constructor constructor.value, // constructor
@ -1741,7 +1776,8 @@ Maybe<ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
auto* var = auto* var =
create<ast::Variable>(decl->source, // source create<ast::Variable>(decl->source, // source
builder_.Symbols().Register(decl->name), // symbol builder_.Symbols().Register(decl->name), // symbol
decl->storage_class, // storage_class decl->storage_class, // storage class
decl->access, // access control
decl->type, // type decl->type, // type
false, // is_const false, // is_const
constructor, // constructor constructor, // constructor
@ -2947,7 +2983,7 @@ Maybe<ast::Decoration*> ParserImpl::decoration() {
if (s == kAccessDecoration) { if (s == kAccessDecoration) {
const char* use = "access decoration"; const char* use = "access decoration";
return expect_paren_block(use, [&]() -> Result { return expect_paren_block(use, [&]() -> Result {
auto val = expect_access_type(); auto val = expect_access("access control");
if (val.errored) if (val.errored)
return Failure::kErrored; return Failure::kErrored;

View File

@ -22,7 +22,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "src/ast/access_control.h" #include "src/ast/access.h"
#include "src/program_builder.h" #include "src/program_builder.h"
#include "src/reader/wgsl/parser_impl_detail.h" #include "src/reader/wgsl/parser_impl_detail.h"
#include "src/reader/wgsl/token.h" #include "src/reader/wgsl/token.h"
@ -208,14 +208,20 @@ class ParserImpl {
TypedIdentifier(const TypedIdentifier& other); TypedIdentifier(const TypedIdentifier& other);
/// Constructor /// Constructor
/// @param type_in parsed type /// @param type_in parsed type
/// @param access_in parsed access
/// @param name_in parsed identifier /// @param name_in parsed identifier
/// @param source_in source to the identifier /// @param source_in source to the identifier
TypedIdentifier(ast::Type* type_in, std::string name_in, Source source_in); TypedIdentifier(ast::Type* type_in,
ast::Access access_in,
std::string name_in,
Source source_in);
/// Destructor /// Destructor
~TypedIdentifier(); ~TypedIdentifier();
/// Parsed type. May be nullptr for inferred types. /// Parsed type. May be nullptr for inferred types.
ast::Type* type = nullptr; ast::Type* type = nullptr;
/// The access control. TODO(crbug.com/tint/846): Remove
ast::Access access = ast::Access::kUndefined;
/// Parsed identifier. /// Parsed identifier.
std::string name; std::string name;
/// Source to the identifier. /// Source to the identifier.
@ -270,10 +276,12 @@ class ParserImpl {
/// @param source_in variable declaration source /// @param source_in variable declaration source
/// @param name_in variable name /// @param name_in variable name
/// @param storage_class_in variable storage class /// @param storage_class_in variable storage class
/// @param access_in variable access control
/// @param type_in variable type /// @param type_in variable type
VarDeclInfo(Source source_in, VarDeclInfo(Source source_in,
std::string name_in, std::string name_in,
ast::StorageClass storage_class_in, ast::StorageClass storage_class_in,
ast::Access access_in,
ast::Type* type_in); ast::Type* type_in);
/// Destructor /// Destructor
~VarDeclInfo(); ~VarDeclInfo();
@ -283,11 +291,21 @@ class ParserImpl {
/// Variable name /// Variable name
std::string name; std::string name;
/// Variable storage class /// Variable storage class
ast::StorageClass storage_class; ast::StorageClass storage_class = ast::StorageClass::kNone;
/// Variable access control
ast::Access access = ast::Access::kUndefined;
/// Variable type /// Variable type
ast::Type* type = nullptr; ast::Type* type = nullptr;
}; };
/// VariableQualifier contains the parsed information for a variable qualifier
struct VariableQualifier {
/// The variable's storage class
ast::StorageClass storage_class = ast::StorageClass::kNone;
/// The variable's access control
ast::Access access = ast::Access::kUndefined;
};
/// Creates a new parser using the given file /// Creates a new parser using the given file
/// @param file the input source file to parse /// @param file the input source file to parse
explicit ParserImpl(Source::File const* file); explicit ParserImpl(Source::File const* file);
@ -400,9 +418,9 @@ class ParserImpl {
Expect<TypedIdentifier> expect_variable_ident_decl( Expect<TypedIdentifier> expect_variable_ident_decl(
const std::string& use, const std::string& use,
bool allow_inferred = false); bool allow_inferred = false);
/// Parses a `variable_storage_decoration` grammar element /// Parses a `variable_qualifier` grammar element
/// @returns the storage class or StorageClass::kNone if none matched /// @returns the variable qualifier information
Maybe<ast::StorageClass> variable_storage_decoration(); Maybe<VariableQualifier> variable_qualifier();
/// Parses a `type_alias` grammar element /// Parses a `type_alias` grammar element
/// @returns the type alias or nullptr on error /// @returns the type alias or nullptr on error
Maybe<ast::Alias*> type_alias(); Maybe<ast::Alias*> type_alias();
@ -438,8 +456,10 @@ class ParserImpl {
/// @returns the parsed function, nullptr otherwise /// @returns the parsed function, nullptr otherwise
Maybe<ast::Function*> function_decl(ast::DecorationList& decos); Maybe<ast::Function*> function_decl(ast::DecorationList& decos);
/// Parses a `texture_sampler_types` grammar element /// Parses a `texture_sampler_types` grammar element
/// TODO(crbug.com/tint/864): Remove decos parameter
/// @param decos the list of decorations for the type declaration.
/// @returns the parsed Type or nullptr if none matched. /// @returns the parsed Type or nullptr if none matched.
Maybe<ast::Type*> texture_sampler_types(); Maybe<ast::Type*> texture_sampler_types(ast::DecorationList& decos);
/// Parses a `sampler_type` grammar element /// Parses a `sampler_type` grammar element
/// @returns the parsed Type or nullptr if none matched. /// @returns the parsed Type or nullptr if none matched.
Maybe<ast::Type*> sampler_type(); Maybe<ast::Type*> sampler_type();
@ -477,10 +497,11 @@ class ParserImpl {
/// not match a stage name. /// not match a stage name.
/// @returns the pipeline stage. /// @returns the pipeline stage.
Expect<ast::PipelineStage> expect_pipeline_stage(); Expect<ast::PipelineStage> expect_pipeline_stage();
/// Parses an access type identifier, erroring if the next token does not /// Parses an access control identifier, erroring if the next token does not
/// match a valid access type name. /// match a valid access control.
/// @param use a description of what was being parsed if an error was raised
/// @returns the parsed access control. /// @returns the parsed access control.
Expect<ast::AccessControl::Access> expect_access_type(); Expect<ast::Access> expect_access(const std::string& use);
/// Parses a builtin identifier, erroring if the next token does not match a /// Parses a builtin identifier, erroring if the next token does not match a
/// valid builtin name. /// valid builtin name.
/// @returns the parsed builtin. /// @returns the parsed builtin.

View File

@ -548,31 +548,31 @@ TEST_F(ParserImplErrorTest, GlobalDeclMultisampledTextureInvalidSubtype) {
} }
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingLessThan) { TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingLessThan) {
EXPECT("var x : [[access(read)]] texture_storage_2d;", EXPECT("var x : texture_storage_2d;",
"test.wgsl:1:44 error: expected '<' for storage texture type\n" "test.wgsl:1:27 error: expected '<' for storage texture type\n"
"var x : [[access(read)]] texture_storage_2d;\n" "var x : texture_storage_2d;\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingGreaterThan) { TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingGreaterThan) {
EXPECT("var x : [[access(read)]] texture_storage_2d<r8uint, read;", EXPECT("var x : texture_storage_2d<r8uint, read;",
"test.wgsl:1:57 error: expected '>' for storage texture type\n" "test.wgsl:1:40 error: expected '>' for storage texture type\n"
"var x : [[access(read)]] texture_storage_2d<r8uint, read;\n" "var x : texture_storage_2d<r8uint, read;\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingSubtype) { TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingSubtype) {
EXPECT("var x : [[access(read)]] texture_storage_2d<>;", EXPECT("var x : texture_storage_2d<>;",
"test.wgsl:1:45 error: invalid format for storage texture type\n" "test.wgsl:1:28 error: invalid format for storage texture type\n"
"var x : [[access(read)]] texture_storage_2d<>;\n" "var x : texture_storage_2d<>;\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingInvalidSubtype) { TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingInvalidSubtype) {
EXPECT("var x : [[access(read)]] texture_storage_2d<1>;", EXPECT("var x : texture_storage_2d<1>;",
"test.wgsl:1:45 error: invalid format for storage texture type\n" "test.wgsl:1:28 error: invalid format for storage texture type\n"
"var x : [[access(read)]] texture_storage_2d<1>;\n" "var x : texture_storage_2d<1>;\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclStructDecoMissingStruct) { TEST_F(ParserImplErrorTest, GlobalDeclStructDecoMissingStruct) {
@ -1018,14 +1018,14 @@ TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingType) {
TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclInvalidClass) { TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclInvalidClass) {
EXPECT("var<fish> i : i32", EXPECT("var<fish> i : i32",
"test.wgsl:1:5 error: invalid storage class for variable decoration\n" "test.wgsl:1:5 error: invalid storage class for variable declaration\n"
"var<fish> i : i32\n" "var<fish> i : i32\n"
" ^^^^\n"); " ^^^^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclMissingGThan) { TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclMissingGThan) {
EXPECT("var<in i : i32", EXPECT("var<in i : i32",
"test.wgsl:1:8 error: expected '>' for variable decoration\n" "test.wgsl:1:8 error: expected '>' for variable declaration\n"
"var<in i : i32\n" "var<in i : i32\n"
" ^\n"); " ^\n");
} }

View File

@ -165,7 +165,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr); EXPECT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:5: invalid storage class for variable decoration"); EXPECT_EQ(p->error(), "1:5: invalid storage class for variable declaration");
} }
TEST_F(ParserImplTest, GlobalVariableDecl_StorageClassIn_Deprecated) { TEST_F(ParserImplTest, GlobalVariableDecl_StorageClassIn_Deprecated) {

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/ast/access_decoration.h"
#include "src/reader/wgsl/parser_impl_test_helper.h" #include "src/reader/wgsl/parser_impl_test_helper.h"
#include "src/sem/depth_texture_type.h" #include "src/sem/depth_texture_type.h"
#include "src/sem/multisampled_texture_type.h" #include "src/sem/multisampled_texture_type.h"
@ -24,7 +25,8 @@ namespace {
TEST_F(ParserImplTest, TextureSamplerTypes_Invalid) { TEST_F(ParserImplTest, TextureSamplerTypes_Invalid) {
auto p = parser("1234"); auto p = parser("1234");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
@ -33,7 +35,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_Invalid) {
TEST_F(ParserImplTest, TextureSamplerTypes_Sampler) { TEST_F(ParserImplTest, TextureSamplerTypes_Sampler) {
auto p = parser("sampler"); auto p = parser("sampler");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
@ -45,7 +48,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_Sampler) {
TEST_F(ParserImplTest, TextureSamplerTypes_SamplerComparison) { TEST_F(ParserImplTest, TextureSamplerTypes_SamplerComparison) {
auto p = parser("sampler_comparison"); auto p = parser("sampler_comparison");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
@ -57,7 +61,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SamplerComparison) {
TEST_F(ParserImplTest, TextureSamplerTypes_DepthTexture) { TEST_F(ParserImplTest, TextureSamplerTypes_DepthTexture) {
auto p = parser("texture_depth_2d"); auto p = parser("texture_depth_2d");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
@ -70,7 +75,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_DepthTexture) {
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_F32) { TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_F32) {
auto p = parser("texture_1d<f32>"); auto p = parser("texture_1d<f32>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
@ -84,7 +90,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_F32) {
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_I32) { TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_I32) {
auto p = parser("texture_2d<i32>"); auto p = parser("texture_2d<i32>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
@ -98,7 +105,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_I32) {
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_U32) { TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_U32) {
auto p = parser("texture_3d<u32>"); auto p = parser("texture_3d<u32>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
@ -112,7 +120,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_U32) {
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_Invalid) { TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_Invalid) {
auto p = parser("texture_1d<abc>"); auto p = parser("texture_1d<abc>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
@ -122,7 +131,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_Invalid) {
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingType) { TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingType) {
auto p = parser("texture_1d<>"); auto p = parser("texture_1d<>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
@ -132,7 +142,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingType) {
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingLessThan) { TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingLessThan) {
auto p = parser("texture_1d"); auto p = parser("texture_1d");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
@ -142,7 +153,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingLessThan) {
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingGreaterThan) { TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingGreaterThan) {
auto p = parser("texture_1d<u32"); auto p = parser("texture_1d<u32");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
@ -152,7 +164,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingGreaterThan) {
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_I32) { TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_I32) {
auto p = parser("texture_multisampled_2d<i32>"); auto p = parser("texture_multisampled_2d<i32>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
@ -166,7 +179,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_I32) {
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_Invalid) { TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_Invalid) {
auto p = parser("texture_multisampled_2d<abc>"); auto p = parser("texture_multisampled_2d<abc>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
@ -176,7 +190,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_Invalid) {
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingType) { TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingType) {
auto p = parser("texture_multisampled_2d<>"); auto p = parser("texture_multisampled_2d<>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
@ -187,7 +202,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_MissingType) {
TEST_F(ParserImplTest, TEST_F(ParserImplTest,
TextureSamplerTypes_MultisampledTexture_MissingLessThan) { TextureSamplerTypes_MultisampledTexture_MissingLessThan) {
auto p = parser("texture_multisampled_2d"); auto p = parser("texture_multisampled_2d");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored); EXPECT_TRUE(t.errored);
@ -197,7 +213,8 @@ TEST_F(ParserImplTest,
TEST_F(ParserImplTest, TEST_F(ParserImplTest,
TextureSamplerTypes_MultisampledTexture_MissingGreaterThan) { TextureSamplerTypes_MultisampledTexture_MissingGreaterThan) {
auto p = parser("texture_multisampled_2d<u32"); auto p = parser("texture_multisampled_2d<u32");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored); EXPECT_TRUE(t.errored);
@ -208,7 +225,8 @@ TEST_F(ParserImplTest,
TEST_F(ParserImplTest, TEST_F(ParserImplTest,
TextureSamplerTypes_StorageTexture_Readonly1dR8Unorm_DEPRECATED) { TextureSamplerTypes_StorageTexture_Readonly1dR8Unorm_DEPRECATED) {
auto p = parser("texture_storage_1d<r8unorm>"); auto p = parser("texture_storage_1d<r8unorm>");
auto t = p->texture_sampler_types(); ast::DecorationList decos{create<ast::AccessDecoration>(ast::Access::kRead)};
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
@ -218,26 +236,25 @@ TEST_F(ParserImplTest,
ASSERT_TRUE(t->Is<ast::StorageTexture>()); ASSERT_TRUE(t->Is<ast::StorageTexture>());
EXPECT_EQ(t->As<ast::StorageTexture>()->image_format(), EXPECT_EQ(t->As<ast::StorageTexture>()->image_format(),
ast::ImageFormat::kR8Unorm); ast::ImageFormat::kR8Unorm);
EXPECT_EQ(t->As<ast::StorageTexture>()->access(), ast::Access::kRead);
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k1d); EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k1d);
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 28u}})); EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 28u}}));
} }
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Readonly1dR8Unorm) { TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Readonly1dR8Unorm) {
auto p = parser("texture_storage_1d<r8unorm, read>"); auto p = parser("texture_storage_1d<r8unorm, read>");
auto a = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(a.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(a.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(a.value, nullptr); ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(a->Is<ast::AccessControl>());
EXPECT_TRUE(a->As<ast::AccessControl>()->IsReadOnly());
auto* t = a->As<ast::AccessControl>()->type();
ASSERT_TRUE(t->Is<ast::Texture>()); ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::StorageTexture>()); ASSERT_TRUE(t->Is<ast::StorageTexture>());
EXPECT_EQ(t->As<ast::StorageTexture>()->image_format(), EXPECT_EQ(t->As<ast::StorageTexture>()->image_format(),
ast::ImageFormat::kR8Unorm); ast::ImageFormat::kR8Unorm);
EXPECT_EQ(t->As<ast::StorageTexture>()->access(), ast::Access::kRead);
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k1d); EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k1d);
EXPECT_EQ(t->source().range, (Source::Range{{1u, 1u}, {1u, 34u}})); EXPECT_EQ(t->source().range, (Source::Range{{1u, 1u}, {1u, 34u}}));
} }
@ -246,7 +263,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Readonly1dR8Unorm) {
TEST_F(ParserImplTest, TEST_F(ParserImplTest,
TextureSamplerTypes_StorageTexture_Writeonly2dR16Float_DEPRECATED) { TextureSamplerTypes_StorageTexture_Writeonly2dR16Float_DEPRECATED) {
auto p = parser("texture_storage_2d<r16float>"); auto p = parser("texture_storage_2d<r16float>");
auto t = p->texture_sampler_types(); ast::DecorationList decos{create<ast::AccessDecoration>(ast::Access::kWrite)};
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
@ -256,33 +274,33 @@ TEST_F(ParserImplTest,
ASSERT_TRUE(t->Is<ast::StorageTexture>()); ASSERT_TRUE(t->Is<ast::StorageTexture>());
EXPECT_EQ(t->As<ast::StorageTexture>()->image_format(), EXPECT_EQ(t->As<ast::StorageTexture>()->image_format(),
ast::ImageFormat::kR16Float); ast::ImageFormat::kR16Float);
EXPECT_EQ(t->As<ast::StorageTexture>()->access(), ast::Access::kWrite);
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d); EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 29u}})); EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 29u}}));
} }
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Writeonly2dR16Float) { TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Writeonly2dR16Float) {
auto p = parser("texture_storage_2d<r16float, write>"); auto p = parser("texture_storage_2d<r16float, write>");
auto a = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(a.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(a.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(a.value, nullptr); ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(a->Is<ast::AccessControl>());
EXPECT_TRUE(a->As<ast::AccessControl>()->IsWriteOnly());
auto* t = a->As<ast::AccessControl>()->type();
ASSERT_TRUE(t->Is<ast::Texture>()); ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::StorageTexture>()); ASSERT_TRUE(t->Is<ast::StorageTexture>());
EXPECT_EQ(t->As<ast::StorageTexture>()->image_format(), EXPECT_EQ(t->As<ast::StorageTexture>()->image_format(),
ast::ImageFormat::kR16Float); ast::ImageFormat::kR16Float);
EXPECT_EQ(t->As<ast::StorageTexture>()->access(), ast::Access::kWrite);
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d); EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_EQ(t->source().range, (Source::Range{{1u, 1u}, {1u, 36u}})); EXPECT_EQ(t->source().range, (Source::Range{{1u, 1u}, {1u, 36u}}));
} }
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidType) { TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidType) {
auto p = parser("texture_storage_1d<abc, read>"); auto p = parser("texture_storage_1d<abc, read>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored); EXPECT_TRUE(t.errored);
@ -291,7 +309,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidType) {
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidAccess) { TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidAccess) {
auto p = parser("texture_storage_1d<r16float, abc>"); auto p = parser("texture_storage_1d<r16float, abc>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored); EXPECT_TRUE(t.errored);
@ -300,7 +319,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidAccess) {
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingType) { TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingType) {
auto p = parser("texture_storage_1d<>"); auto p = parser("texture_storage_1d<>");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored); EXPECT_TRUE(t.errored);
@ -309,7 +329,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingType) {
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingLessThan) { TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingLessThan) {
auto p = parser("texture_storage_1d"); auto p = parser("texture_storage_1d");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored); EXPECT_TRUE(t.errored);
@ -318,7 +339,8 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingLessThan) {
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingGreaterThan) { TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingGreaterThan) {
auto p = parser("texture_storage_1d<r8unorm, read"); auto p = parser("texture_storage_1d<r8unorm, read");
auto t = p->texture_sampler_types(); ast::DecorationList decos;
auto t = p->texture_sampler_types(decos);
EXPECT_EQ(t.value, nullptr); EXPECT_EQ(t.value, nullptr);
EXPECT_FALSE(t.matched); EXPECT_FALSE(t.matched);
EXPECT_TRUE(t.errored); EXPECT_TRUE(t.errored);

View File

@ -87,7 +87,7 @@ TEST_F(ParserImplTest, VariableDecl_InvalidStorageClass) {
EXPECT_FALSE(v.matched); EXPECT_FALSE(v.matched);
EXPECT_TRUE(v.errored); EXPECT_TRUE(v.errored);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:5: invalid storage class for variable decoration"); EXPECT_EQ(p->error(), "1:5: invalid storage class for variable declaration");
} }
} // namespace } // namespace

View File

@ -84,7 +84,9 @@ TEST_F(ParserImplTest, VariableIdentDecl_InvalidType) {
ASSERT_EQ(p->error(), "1:10: unknown constructed type 'invalid'"); ASSERT_EQ(p->error(), "1:10: unknown constructed type 'invalid'");
} }
TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithTextureAccessDeco_Read) { // TODO(crbug.com/tint/846): Remove
TEST_F(ParserImplTest,
VariableIdentDecl_ParsesWithTextureAccessDeco_Read_DEPRECATED) {
auto p = parser("my_var : [[access(read)]] texture_storage_1d<r32float>"); auto p = parser("my_var : [[access(read)]] texture_storage_1d<r32float>");
auto decl = p->expect_variable_ident_decl("test"); auto decl = p->expect_variable_ident_decl("test");
@ -92,13 +94,17 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithTextureAccessDeco_Read) {
ASSERT_FALSE(decl.errored); ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var"); ASSERT_EQ(decl->name, "my_var");
ASSERT_NE(decl->type, nullptr); ASSERT_NE(decl->type, nullptr);
ASSERT_TRUE(decl->type->Is<ast::AccessControl>()); ASSERT_TRUE(decl->type->Is<ast::StorageTexture>());
EXPECT_TRUE(decl->type->As<ast::AccessControl>()->IsReadOnly()); EXPECT_TRUE(decl->type->As<ast::StorageTexture>()->is_read_only());
ASSERT_TRUE(
decl->type->As<ast::AccessControl>()->type()->Is<ast::StorageTexture>()); EXPECT_EQ(p->error(),
"1:54: use of deprecated language feature: access control is "
"expected as last parameter of storage textures");
} }
TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithTextureAccessDeco_Write) { // TODO(crbug.com/tint/846): Remove
TEST_F(ParserImplTest,
VariableIdentDecl_ParsesWithTextureAccessDeco_Write_DEPRECATED) {
auto p = parser("my_var : [[access(write)]] texture_storage_1d<r32float>"); auto p = parser("my_var : [[access(write)]] texture_storage_1d<r32float>");
auto decl = p->expect_variable_ident_decl("test"); auto decl = p->expect_variable_ident_decl("test");
@ -106,14 +112,17 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithTextureAccessDeco_Write) {
ASSERT_FALSE(decl.errored); ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var"); ASSERT_EQ(decl->name, "my_var");
ASSERT_NE(decl->type, nullptr); ASSERT_NE(decl->type, nullptr);
ASSERT_TRUE(decl->type->Is<ast::AccessControl>()); ASSERT_TRUE(decl->type->Is<ast::StorageTexture>());
EXPECT_TRUE(decl->type->As<ast::AccessControl>()->IsWriteOnly()); EXPECT_TRUE(decl->type->As<ast::StorageTexture>()->is_write_only());
ASSERT_TRUE(
decl->type->As<ast::AccessControl>()->type()->Is<ast::StorageTexture>()); EXPECT_EQ(p->error(),
"1:55: use of deprecated language feature: access control is "
"expected as last parameter of storage textures");
} }
TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_Read) { // TODO(crbug.com/tint/846): Remove
auto p = parser("my_var : [[access(read)]] S"); TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_Read_DEPRECATED) {
auto p = parser("var my_var : [[access(read)]] S;");
auto* mem = Member("a", ty.i32(), ast::DecorationList{}); auto* mem = Member("a", ty.i32(), ast::DecorationList{});
ast::StructMemberList members; ast::StructMemberList members;
@ -127,17 +136,25 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_Read) {
p->register_constructed("S", s); p->register_constructed("S", s);
auto decl = p->expect_variable_ident_decl("test"); auto res = p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(res.errored) << p->error();
ASSERT_FALSE(decl.errored); ASSERT_NE(p->builder().AST().GlobalVariables().size(), 0u);
ASSERT_EQ(decl->name, "my_var"); auto* decl = p->builder().AST().GlobalVariables()[0];
ASSERT_NE(decl->type, nullptr); ASSERT_NE(decl, nullptr);
ASSERT_TRUE(decl->type->Is<ast::AccessControl>()); ASSERT_EQ(decl->symbol(), p->builder().Symbols().Get("my_var"));
EXPECT_TRUE(decl->type->As<ast::AccessControl>()->IsReadOnly()); ASSERT_NE(decl->type(), nullptr);
EXPECT_TRUE(decl->type()->Is<ast::TypeName>());
EXPECT_EQ(decl->declared_access(), ast::Access::kRead);
EXPECT_EQ(p->error(),
"1:1: use of deprecated language feature: declare access with "
"var<none, read> instead of using [[access]] decoration");
} }
TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_ReadWrite) { // TODO(crbug.com/tint/846): Remove
auto p = parser("my_var : [[access(read_write)]] S"); TEST_F(ParserImplTest,
VariableIdentDecl_ParsesWithAccessDeco_ReadWrite_DEPRECATED) {
auto p = parser("var my_var : [[access(read_write)]] S;");
auto* mem = Member("a", ty.i32(), ast::DecorationList{}); auto* mem = Member("a", ty.i32(), ast::DecorationList{});
ast::StructMemberList members; ast::StructMemberList members;
@ -151,16 +168,23 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_ReadWrite) {
p->register_constructed("S", s); p->register_constructed("S", s);
auto decl = p->expect_variable_ident_decl("test"); auto res = p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(res.errored) << p->error();
ASSERT_FALSE(decl.errored); ASSERT_NE(p->builder().AST().GlobalVariables().size(), 0u);
ASSERT_EQ(decl->name, "my_var"); auto* decl = p->builder().AST().GlobalVariables()[0];
ASSERT_NE(decl->type, nullptr); ASSERT_NE(decl, nullptr);
ASSERT_TRUE(decl->type->Is<ast::AccessControl>()); ASSERT_EQ(decl->symbol(), p->builder().Symbols().Get("my_var"));
EXPECT_TRUE(decl->type->As<ast::AccessControl>()->IsReadWrite()); ASSERT_NE(decl->type(), nullptr);
EXPECT_TRUE(decl->type()->Is<ast::TypeName>());
EXPECT_EQ(decl->declared_access(), ast::Access::kReadWrite);
EXPECT_EQ(p->error(),
"1:1: use of deprecated language feature: declare access with "
"var<none, read_write> instead of using [[access]] decoration");
} }
TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDecoFail) { // TODO(crbug.com/tint/846): Remove
TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDecoFail_DEPRECATED) {
auto p = parser("my_var : [[access(read), access(read_write)]] S"); auto p = parser("my_var : [[access(read), access(read_write)]] S");
auto* mem = Member("a", ty.i32(), ast::DecorationList{}); auto* mem = Member("a", ty.i32(), ast::DecorationList{});
@ -181,7 +205,9 @@ TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDecoFail) {
ASSERT_EQ(p->error(), "1:1: multiple access decorations not allowed"); ASSERT_EQ(p->error(), "1:1: multiple access decorations not allowed");
} }
TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDeco_MultiBlock_Fail) { // TODO(crbug.com/tint/846): Remove
TEST_F(ParserImplTest,
VariableIdentDecl_MultipleAccessDeco_MultiBlock_Fail_DEPRECATED) {
auto p = parser("my_var : [[access(read)]][[access(read_write)]] S"); auto p = parser("my_var : [[access(read)]][[access(read_write)]] S");
auto* mem = Member("a", ty.i32(), ast::DecorationList{}); auto* mem = Member("a", ty.i32(), ast::DecorationList{});
@ -202,7 +228,8 @@ TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDeco_MultiBlock_Fail) {
ASSERT_EQ(p->error(), "1:1: multiple access decorations not allowed"); ASSERT_EQ(p->error(), "1:1: multiple access decorations not allowed");
} }
TEST_F(ParserImplTest, VariableIdentDecl_AccessDecoBadValue) { // TODO(crbug.com/tint/846): Remove
TEST_F(ParserImplTest, VariableIdentDecl_AccessDecoBadValue_DEPRECATED) {
auto p = parser("my_var : [[access(unknown)]] S"); auto p = parser("my_var : [[access(unknown)]] S");
auto decl = p->expect_variable_ident_decl("test"); auto decl = p->expect_variable_ident_decl("test");
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
@ -210,12 +237,13 @@ TEST_F(ParserImplTest, VariableIdentDecl_AccessDecoBadValue) {
ASSERT_EQ(p->error(), "1:19: invalid value for access decoration"); ASSERT_EQ(p->error(), "1:19: invalid value for access decoration");
} }
TEST_F(ParserImplTest, VariableIdentDecl_AccessDecoIllegalValue) { // TODO(crbug.com/tint/846): Remove
TEST_F(ParserImplTest, VariableIdentDecl_AccessDecoIllegalValue_DEPRECATED) {
auto p = parser("my_var : [[access(1)]] S"); auto p = parser("my_var : [[access(1)]] S");
auto decl = p->expect_variable_ident_decl("test"); auto decl = p->expect_variable_ident_decl("test");
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored); ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:19: expected identifier for access_type"); ASSERT_EQ(p->error(), "1:19: expected identifier for access control");
} }
TEST_F(ParserImplTest, VariableIdentDecl_NonAccessDecoFail) { TEST_F(ParserImplTest, VariableIdentDecl_NonAccessDecoFail) {
@ -240,27 +268,27 @@ TEST_F(ParserImplTest, VariableIdentDecl_NonAccessDecoFail) {
} }
TEST_F(ParserImplTest, VariableIdentDecl_DecorationMissingRightBlock) { TEST_F(ParserImplTest, VariableIdentDecl_DecorationMissingRightBlock) {
auto p = parser("my_var : [[access(read) S"); auto p = parser("my_var : [[stride(4) S");
auto decl = p->expect_variable_ident_decl("test"); auto decl = p->expect_variable_ident_decl("test");
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored); ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:25: expected ']]' for decoration list"); ASSERT_EQ(p->error(), "1:22: expected ']]' for decoration list");
} }
TEST_F(ParserImplTest, VariableIdentDecl_DecorationMissingRightParen) { TEST_F(ParserImplTest, VariableIdentDecl_DecorationMissingRightParen) {
auto p = parser("my_var : [[access(read]] S"); auto p = parser("my_var : [[stride(4]] S");
auto decl = p->expect_variable_ident_decl("test"); auto decl = p->expect_variable_ident_decl("test");
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored); ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:23: expected ')' for access decoration"); ASSERT_EQ(p->error(), "1:20: expected ')' for stride decoration");
} }
TEST_F(ParserImplTest, VariableIdentDecl_DecorationMissingLeftParen) { TEST_F(ParserImplTest, VariableIdentDecl_DecorationMissingLeftParen) {
auto p = parser("my_var : [[access read)]] S"); auto p = parser("my_var : [[stride 4)]] S");
auto decl = p->expect_variable_ident_decl("test"); auto decl = p->expect_variable_ident_decl("test");
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_TRUE(decl.errored); ASSERT_TRUE(decl.errored);
ASSERT_EQ(p->error(), "1:19: expected '(' for access decoration"); ASSERT_EQ(p->error(), "1:19: expected '(' for stride decoration");
} }
TEST_F(ParserImplTest, VariableIdentDecl_DecorationEmpty) { TEST_F(ParserImplTest, VariableIdentDecl_DecorationEmpty) {

View File

@ -21,64 +21,81 @@ namespace {
struct VariableStorageData { struct VariableStorageData {
const char* input; const char* input;
ast::StorageClass result; ast::StorageClass storage_class;
ast::Access access;
}; };
inline std::ostream& operator<<(std::ostream& out, VariableStorageData data) { inline std::ostream& operator<<(std::ostream& out, VariableStorageData data) {
out << std::string(data.input); out << std::string(data.input);
return out; return out;
} }
class VariableStorageTest class VariableQualifierTest
: public ParserImplTestWithParam<VariableStorageData> {}; : public ParserImplTestWithParam<VariableStorageData> {};
TEST_P(VariableStorageTest, Parses) { TEST_P(VariableQualifierTest, ParsesStorageClass) {
auto params = GetParam(); auto params = GetParam();
auto p = parser(std::string("<") + params.input + ">"); auto p = parser(std::string("<") + params.input + ">");
auto sc = p->variable_storage_decoration(); auto sc = p->variable_qualifier();
EXPECT_FALSE(p->has_error()); EXPECT_FALSE(p->has_error());
EXPECT_FALSE(sc.errored); EXPECT_FALSE(sc.errored);
EXPECT_TRUE(sc.matched); EXPECT_TRUE(sc.matched);
EXPECT_EQ(sc.value, params.result); EXPECT_EQ(sc->storage_class, params.storage_class);
EXPECT_EQ(sc->access, params.access);
auto t = p->next(); auto t = p->next();
EXPECT_TRUE(t.IsEof()); EXPECT_TRUE(t.IsEof());
} }
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
ParserImplTest, ParserImplTest,
VariableStorageTest, VariableQualifierTest,
testing::Values( testing::Values(
VariableStorageData{"in", ast::StorageClass::kInput}, VariableStorageData{"in", ast::StorageClass::kInput,
VariableStorageData{"out", ast::StorageClass::kOutput}, ast::Access::kUndefined},
VariableStorageData{"uniform", ast::StorageClass::kUniform}, VariableStorageData{"out", ast::StorageClass::kOutput,
VariableStorageData{"workgroup", ast::StorageClass::kWorkgroup}, ast::Access::kUndefined},
VariableStorageData{"storage", ast::StorageClass::kStorage}, VariableStorageData{"uniform", ast::StorageClass::kUniform,
VariableStorageData{"storage_buffer", ast::StorageClass::kStorage}, ast::Access::kUndefined},
VariableStorageData{"image", ast::StorageClass::kImage}, VariableStorageData{"workgroup", ast::StorageClass::kWorkgroup,
VariableStorageData{"private", ast::StorageClass::kPrivate}, ast::Access::kUndefined},
VariableStorageData{"function", ast::StorageClass::kFunction})); VariableStorageData{"storage", ast::StorageClass::kStorage,
ast::Access::kUndefined},
VariableStorageData{"storage_buffer", ast::StorageClass::kStorage,
ast::Access::kUndefined},
VariableStorageData{"image", ast::StorageClass::kImage,
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},
VariableStorageData{"storage, write", ast::StorageClass::kStorage,
ast::Access::kWrite},
VariableStorageData{"storage, read_write", ast::StorageClass::kStorage,
ast::Access::kReadWrite}));
TEST_F(ParserImplTest, VariableStorageDecoration_NoMatch) { TEST_F(ParserImplTest, VariableQualifier_NoMatch) {
auto p = parser("<not-a-storage-class>"); auto p = parser("<not-a-storage-class>");
auto sc = p->variable_storage_decoration(); auto sc = p->variable_qualifier();
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_TRUE(sc.errored); EXPECT_TRUE(sc.errored);
EXPECT_FALSE(sc.matched); EXPECT_FALSE(sc.matched);
EXPECT_EQ(p->error(), "1:2: invalid storage class for variable decoration"); EXPECT_EQ(p->error(), "1:2: invalid storage class for variable declaration");
} }
TEST_F(ParserImplTest, VariableStorageDecoration_Empty) { TEST_F(ParserImplTest, VariableQualifier_Empty) {
auto p = parser("<>"); auto p = parser("<>");
auto sc = p->variable_storage_decoration(); auto sc = p->variable_qualifier();
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_TRUE(sc.errored); EXPECT_TRUE(sc.errored);
EXPECT_FALSE(sc.matched); EXPECT_FALSE(sc.matched);
EXPECT_EQ(p->error(), "1:2: invalid storage class for variable decoration"); EXPECT_EQ(p->error(), "1:2: invalid storage class for variable declaration");
} }
TEST_F(ParserImplTest, VariableStorageDecoration_MissingLessThan) { TEST_F(ParserImplTest, VariableQualifier_MissingLessThan) {
auto p = parser("in>"); auto p = parser("in>");
auto sc = p->variable_storage_decoration(); auto sc = p->variable_qualifier();
EXPECT_FALSE(p->has_error()); EXPECT_FALSE(p->has_error());
EXPECT_FALSE(sc.errored); EXPECT_FALSE(sc.errored);
EXPECT_FALSE(sc.matched); EXPECT_FALSE(sc.matched);
@ -87,13 +104,24 @@ TEST_F(ParserImplTest, VariableStorageDecoration_MissingLessThan) {
ASSERT_TRUE(t.IsIn()); ASSERT_TRUE(t.IsIn());
} }
TEST_F(ParserImplTest, VariableStorageDecoration_MissingGreaterThan) { TEST_F(ParserImplTest, VariableQualifier_MissingLessThan_AfterSC) {
auto p = parser("in, >");
auto sc = p->variable_qualifier();
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(sc.errored);
EXPECT_FALSE(sc.matched);
auto t = p->next();
ASSERT_TRUE(t.IsIn());
}
TEST_F(ParserImplTest, VariableQualifier_MissingGreaterThan) {
auto p = parser("<in"); auto p = parser("<in");
auto sc = p->variable_storage_decoration(); auto sc = p->variable_qualifier();
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_TRUE(sc.errored); EXPECT_TRUE(sc.errored);
EXPECT_FALSE(sc.matched); EXPECT_FALSE(sc.matched);
EXPECT_EQ(p->error(), "1:4: expected '>' for variable decoration"); EXPECT_EQ(p->error(), "1:4: expected '>' for variable declaration");
} }
} // namespace } // namespace

View File

@ -156,14 +156,14 @@ TEST_F(ResolverAssignmentValidationTest, AssignToConstant_Fail) {
} }
TEST_F(ResolverAssignmentValidationTest, AssignNonStorable_Fail) { TEST_F(ResolverAssignmentValidationTest, AssignNonStorable_Fail) {
// var a : [[access(read)]] texture_storage_1d<rgba8unorm>; // var a : texture_storage_1d<rgba8unorm, read>;
// var b : [[access(read)]] texture_storage_1d<rgba8unorm>; // var b : texture_storage_1d<rgba8unorm, read>;
// a = b; // a = b;
auto make_type = [&] { auto make_type = [&] {
auto* tex_type = ty.storage_texture(ast::TextureDimension::k1d, return ty.storage_texture(ast::TextureDimension::k1d,
ast::ImageFormat::kRgba8Unorm); ast::ImageFormat::kRgba8Unorm,
return ty.access(ast::AccessControl::kRead, tex_type); ast::Access::kRead);
}; };
Global("a", make_type(), ast::StorageClass::kNone, Global("a", make_type(), ast::StorageClass::kNone,
@ -182,7 +182,7 @@ TEST_F(ResolverAssignmentValidationTest, AssignNonStorable_Fail) {
EXPECT_FALSE(r()->Resolve()); EXPECT_FALSE(r()->Resolve());
EXPECT_EQ( EXPECT_EQ(
r()->error(), r()->error(),
R"(12:34 error: '[[access(read)]] texture_storage_1d<rgba8unorm>' is not storable)"); R"(12:34 error: 'texture_storage_1d<rgba8unorm, read>' is not storable)");
} }
} // namespace } // namespace

View File

@ -30,7 +30,6 @@ namespace DecorationTests {
namespace { namespace {
enum class DecorationKind { enum class DecorationKind {
kAccess,
kAlign, kAlign,
kBinding, kBinding,
kBuiltin, kBuiltin,
@ -68,9 +67,6 @@ static ast::DecorationList createDecorations(const Source& source,
ProgramBuilder& builder, ProgramBuilder& builder,
DecorationKind kind) { DecorationKind kind) {
switch (kind) { switch (kind) {
case DecorationKind::kAccess:
return {builder.create<ast::AccessDecoration>(source,
ast::AccessControl::kRead)};
case DecorationKind::kAlign: case DecorationKind::kAlign:
return {builder.create<ast::StructMemberAlignDecoration>(source, 4u)}; return {builder.create<ast::StructMemberAlignDecoration>(source, 4u)};
case DecorationKind::kBinding: case DecorationKind::kBinding:
@ -122,8 +118,7 @@ TEST_P(FunctionReturnTypeDecorationTest, IsValid) {
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
ResolverDecorationValidationTest, ResolverDecorationValidationTest,
FunctionReturnTypeDecorationTest, FunctionReturnTypeDecorationTest,
testing::Values(TestParams{DecorationKind::kAccess, false}, testing::Values(TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kBinding, false}, TestParams{DecorationKind::kBinding, false},
TestParams{DecorationKind::kBuiltin, true}, TestParams{DecorationKind::kBuiltin, true},
TestParams{DecorationKind::kGroup, false}, TestParams{DecorationKind::kGroup, false},
@ -162,8 +157,7 @@ TEST_P(ArrayDecorationTest, IsValid) {
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
ResolverDecorationValidationTest, ResolverDecorationValidationTest,
ArrayDecorationTest, ArrayDecorationTest,
testing::Values(TestParams{DecorationKind::kAccess, false}, testing::Values(TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kBinding, false}, TestParams{DecorationKind::kBinding, false},
TestParams{DecorationKind::kBuiltin, false}, TestParams{DecorationKind::kBuiltin, false},
TestParams{DecorationKind::kGroup, false}, TestParams{DecorationKind::kGroup, false},
@ -197,8 +191,7 @@ TEST_P(StructDecorationTest, IsValid) {
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
ResolverDecorationValidationTest, ResolverDecorationValidationTest,
StructDecorationTest, StructDecorationTest,
testing::Values(TestParams{DecorationKind::kAccess, false}, testing::Values(TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kBinding, false}, TestParams{DecorationKind::kBinding, false},
TestParams{DecorationKind::kBuiltin, false}, TestParams{DecorationKind::kBuiltin, false},
TestParams{DecorationKind::kGroup, false}, TestParams{DecorationKind::kGroup, false},
@ -234,8 +227,7 @@ TEST_P(StructMemberDecorationTest, IsValid) {
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
ResolverDecorationValidationTest, ResolverDecorationValidationTest,
StructMemberDecorationTest, StructMemberDecorationTest,
testing::Values(TestParams{DecorationKind::kAccess, false}, testing::Values(TestParams{DecorationKind::kAlign, true},
TestParams{DecorationKind::kAlign, true},
TestParams{DecorationKind::kBinding, false}, TestParams{DecorationKind::kBinding, false},
TestParams{DecorationKind::kBuiltin, true}, TestParams{DecorationKind::kBuiltin, true},
TestParams{DecorationKind::kGroup, false}, TestParams{DecorationKind::kGroup, false},
@ -277,8 +269,7 @@ TEST_P(VariableDecorationTest, IsValid) {
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
ResolverDecorationValidationTest, ResolverDecorationValidationTest,
VariableDecorationTest, VariableDecorationTest,
testing::Values(TestParams{DecorationKind::kAccess, false}, testing::Values(TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kBinding, false}, TestParams{DecorationKind::kBinding, false},
TestParams{DecorationKind::kBuiltin, true}, TestParams{DecorationKind::kBuiltin, true},
TestParams{DecorationKind::kGroup, false}, TestParams{DecorationKind::kGroup, false},
@ -312,8 +303,7 @@ TEST_P(ConstantDecorationTest, IsValid) {
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
ResolverDecorationValidationTest, ResolverDecorationValidationTest,
ConstantDecorationTest, ConstantDecorationTest,
testing::Values(TestParams{DecorationKind::kAccess, false}, testing::Values(TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kBinding, false}, TestParams{DecorationKind::kBinding, false},
TestParams{DecorationKind::kBuiltin, false}, TestParams{DecorationKind::kBuiltin, false},
TestParams{DecorationKind::kGroup, false}, TestParams{DecorationKind::kGroup, false},
@ -346,8 +336,7 @@ TEST_P(FunctionDecorationTest, IsValid) {
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
ResolverDecorationValidationTest, ResolverDecorationValidationTest,
FunctionDecorationTest, FunctionDecorationTest,
testing::Values(TestParams{DecorationKind::kAccess, false}, testing::Values(TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kAlign, false},
TestParams{DecorationKind::kBinding, false}, TestParams{DecorationKind::kBinding, false},
TestParams{DecorationKind::kBuiltin, false}, TestParams{DecorationKind::kBuiltin, false},
TestParams{DecorationKind::kGroup, false}, TestParams{DecorationKind::kGroup, false},
@ -523,8 +512,8 @@ TEST_F(ResourceDecorationTest, UniformBufferMissingBinding) {
TEST_F(ResourceDecorationTest, StorageBufferMissingBinding) { TEST_F(ResourceDecorationTest, StorageBufferMissingBinding) {
auto* s = Structure("S", {Member("x", ty.i32())}, auto* s = Structure("S", {Member("x", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kRead, s); Global(Source{{12, 34}}, "G", s, ast::StorageClass::kStorage,
Global(Source{{12, 34}}, "G", ac, ast::StorageClass::kStorage); ast::Access::kRead);
EXPECT_FALSE(r()->Resolve()); EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), EXPECT_EQ(r()->error(),

View File

@ -28,8 +28,9 @@ using ResolverHostShareableValidationTest = ResolverTest;
TEST_F(ResolverHostShareableValidationTest, BoolMember) { TEST_F(ResolverHostShareableValidationTest, BoolMember) {
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.bool_())}, auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.bool_())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kRead, s);
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage,
ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -47,8 +48,9 @@ TEST_F(ResolverHostShareableValidationTest, BoolMember) {
TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) { TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) {
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.vec3<bool>())}, auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.vec3<bool>())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kRead, s);
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage,
ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -68,10 +70,10 @@ TEST_F(ResolverHostShareableValidationTest, Aliases) {
AST().AddConstructedType(a1); AST().AddConstructedType(a1);
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", a1)}, auto* s = Structure("S", {Member(Source{{12, 34}}, "x", a1)},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kRead, s); auto* a2 = ty.alias("a2", s);
auto* a2 = ty.alias("a2", ac);
AST().AddConstructedType(a2); AST().AddConstructedType(a2);
Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage, Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage,
ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -93,8 +95,9 @@ TEST_F(ResolverHostShareableValidationTest, NestedStructures) {
auto* s = Structure("S", {Member(Source{{7, 8}}, "m", i3)}, auto* s = Structure("S", {Member(Source{{7, 8}}, "m", i3)},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kRead, s);
Global(Source{{9, 10}}, "g", a, ast::StorageClass::kStorage, Global(Source{{9, 10}}, "g", s, ast::StorageClass::kStorage,
ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -135,8 +138,9 @@ TEST_F(ResolverHostShareableValidationTest, NoError) {
auto* s = Structure("S", {Member(Source{{7, 8}}, "m", i3)}, auto* s = Structure("S", {Member(Source{{7, 8}}, "m", i3)},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kRead, s);
Global(Source{{9, 10}}, "g", a, ast::StorageClass::kStorage, Global(Source{{9, 10}}, "g", s, ast::StorageClass::kStorage,
ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),

View File

@ -276,12 +276,11 @@ TEST_P(ResolverIntrinsicTest_StorageTextureOperation, TextureLoadRo) {
auto format = GetParam().format; auto format = GetParam().format;
auto* coords_type = GetCoordsType(dim, ty.i32()); auto* coords_type = GetCoordsType(dim, ty.i32());
auto* texture_type = ty.storage_texture(dim, format); auto* texture_type = ty.storage_texture(dim, format, ast::Access::kRead);
auto* ro_texture_type = ty.access(ast::AccessControl::kRead, texture_type);
ast::ExpressionList call_params; ast::ExpressionList call_params;
add_call_param("texture", ro_texture_type, &call_params); add_call_param("texture", texture_type, &call_params);
add_call_param("coords", coords_type, &call_params); add_call_param("coords", coords_type, &call_params);
if (ast::IsTextureArray(dim)) { if (ast::IsTextureArray(dim)) {
@ -769,8 +768,7 @@ TEST_F(ResolverIntrinsicDataTest, ArrayLength_Vector) {
auto* ary = ty.array<i32>(); auto* ary = ty.array<i32>();
auto* str = Structure("S", {Member("x", ary)}, auto* str = Structure("S", {Member("x", ary)},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kRead, str); Global("a", str, ast::StorageClass::kStorage, ast::Access::kRead,
Global("a", ac, ast::StorageClass::kStorage,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),

View File

@ -287,13 +287,6 @@ sem::Type* Resolver::Type(const ast::Type* ty) {
if (ty->Is<ast::F32>()) { if (ty->Is<ast::F32>()) {
return builder_->create<sem::F32>(); return builder_->create<sem::F32>();
} }
if (auto* t = ty->As<ast::AccessControl>()) {
TINT_SCOPED_ASSIGNMENT(current_access_control_, t);
if (auto* el = Type(t->type())) {
return el;
}
return nullptr;
}
if (auto* t = ty->As<ast::Vector>()) { if (auto* t = ty->As<ast::Vector>()) {
if (auto* el = Type(t->type())) { if (auto* el = Type(t->type())) {
return builder_->create<sem::Vector>(const_cast<sem::Type*>(el), return builder_->create<sem::Vector>(const_cast<sem::Type*>(el),
@ -341,14 +334,11 @@ sem::Type* Resolver::Type(const ast::Type* ty) {
} }
if (auto* t = ty->As<ast::StorageTexture>()) { if (auto* t = ty->As<ast::StorageTexture>()) {
if (auto* el = Type(t->type())) { if (auto* el = Type(t->type())) {
if (!current_access_control_) { if (!ValidateStorageTexture(t)) {
diagnostics_.add_error("storage textures must have access control",
t->source());
return nullptr; return nullptr;
} }
return builder_->create<sem::StorageTexture>( return builder_->create<sem::StorageTexture>(
t->dim(), t->image_format(), t->dim(), t->image_format(), t->access(),
current_access_control_->access_control(),
const_cast<sem::Type*>(el)); const_cast<sem::Type*>(el));
} }
return nullptr; return nullptr;
@ -377,6 +367,39 @@ sem::Type* Resolver::Type(const ast::Type* ty) {
return s; return s;
} }
bool Resolver::ValidateStorageTexture(const ast::StorageTexture* t) {
switch (t->access()) {
case ast::Access::kUndefined:
diagnostics_.add_error("storage textures must have access control",
t->source());
return false;
case ast::Access::kReadWrite:
diagnostics_.add_error(
"storage textures only support read-only and write-only access",
t->source());
return false;
case ast::Access::kRead:
case ast::Access::kWrite:
break;
}
if (!IsValidStorageTextureDimension(t->dim())) {
diagnostics_.add_error(
"cube dimensions for storage textures are not supported", t->source());
return false;
}
if (!IsValidStorageTextureImageFormat(t->image_format())) {
diagnostics_.add_error(
"image format must be one of the texel formats specified for storage "
"textues in https://gpuweb.github.io/gpuweb/wgsl/#texel-formats",
t->source());
return false;
}
return true;
}
Resolver::VariableInfo* Resolver::Variable(ast::Variable* var, Resolver::VariableInfo* Resolver::Variable(ast::Variable* var,
VariableKind kind) { VariableKind kind) {
if (variable_to_info_.count(var)) { if (variable_to_info_.count(var)) {
@ -466,35 +489,17 @@ Resolver::VariableInfo* Resolver::Variable(ast::Variable* var,
return nullptr; return nullptr;
} }
// TODO(crbug.com/tint/802): Temporary while ast::AccessControl exits. auto access = var->declared_access();
auto find_first_access_control = if (access == ast::Access::kUndefined &&
[this](const ast::Type* ty) -> const ast::AccessControl* { storage_class == ast::StorageClass::kStorage) {
if (ty == nullptr) { // https://gpuweb.github.io/gpuweb/wgsl/#access-mode-defaults
return nullptr; // For the storage storage class, the access mode is optional, and defaults
} // to read.
if (const ast::AccessControl* ac = ty->As<ast::AccessControl>()) { access = ast::Access::kRead;
return ac; }
}
while (auto* tn = ty->As<ast::TypeName>()) {
auto it = named_type_info_.find(tn->name());
if (it == named_type_info_.end()) {
break;
}
auto* alias = it->second.ast->As<ast::Alias>();
if (!alias) {
break;
}
ty = alias->type();
if (auto* ac = ty->As<ast::AccessControl>()) {
return ac;
}
}
return nullptr;
};
auto* access_control = find_first_access_control(var->type());
auto* info = variable_infos_.Create(var, const_cast<sem::Type*>(type), auto* info = variable_infos_.Create(var, const_cast<sem::Type*>(type),
type_name, storage_class, access_control); type_name, storage_class, access);
variable_to_info_.emplace(var, info); variable_to_info_.emplace(var, info);
return info; return info;
@ -658,25 +663,31 @@ bool Resolver::ValidateGlobalVariable(const VariableInfo* info) {
} }
} }
// https://gpuweb.github.io/gpuweb/wgsl/#variable-declaration
// The access mode always has a default, and except for variables in the
// storage storage class, must not be written.
if (info->storage_class != ast::StorageClass::kStorage &&
info->declaration->declared_access() != ast::Access::kUndefined) {
diagnostics_.add_error(
"variables declared not declared in the <storage> storage class must "
"not declare an access control",
info->declaration->source());
return false;
}
switch (info->storage_class) { switch (info->storage_class) {
case ast::StorageClass::kStorage: { case ast::StorageClass::kStorage: {
// https://gpuweb.github.io/gpuweb/wgsl/#variable-declaration
// Variables in the storage storage class and variables with a storage
// texture type must have an access attribute applied to the store type.
// https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables // https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
// A variable in the storage storage class is a storage buffer variable. // A variable in the storage storage class is a storage buffer variable.
// Its store type must be a host-shareable structure type with block // Its store type must be a host-shareable structure type with block
// attribute, satisfying the storage class constraints. // attribute, satisfying the storage class constraints.
auto* str = info->access_control auto* str = info->type->UnwrapRef()->As<sem::Struct>();
? info->type->UnwrapRef()->As<sem::Struct>()
: nullptr;
if (!str) { if (!str) {
diagnostics_.add_error( diagnostics_.add_error(
"variables declared in the <storage> storage class must be of an " "variables declared in the <storage> storage class must be of a "
"[[access]] qualified structure type", "structure type",
info->declaration->source()); info->declaration->source());
return false; return false;
} }
@ -756,33 +767,6 @@ bool Resolver::ValidateVariable(const VariableInfo* info) {
} }
} }
if (auto* storage_tex = info->type->UnwrapRef()->As<sem::StorageTexture>()) {
if (info->access_control->access_control() ==
ast::AccessControl::kReadWrite) {
diagnostics_.add_error(
"storage textures only support read-only and write-only access",
var->source());
return false;
}
if (!IsValidStorageTextureDimension(storage_tex->dim())) {
diagnostics_.add_error(
"cube dimensions for storage textures are not "
"supported",
var->source());
return false;
}
if (!IsValidStorageTextureImageFormat(storage_tex->image_format())) {
diagnostics_.add_error(
"image format must be one of the texel formats specified for "
"storage textues in "
"https://gpuweb.github.io/gpuweb/wgsl/#texel-formats",
var->source());
return false;
}
}
if (storage_type->is_handle() && if (storage_type->is_handle() &&
var->declared_storage_class() != ast::StorageClass::kNone) { var->declared_storage_class() != ast::StorageClass::kNone) {
// https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables // https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
@ -2584,9 +2568,7 @@ void Resolver::CreateSemanticNodes() const {
sem_var = builder_->create<sem::Variable>(var, info->type, constant_id); sem_var = builder_->create<sem::Variable>(var, info->type, constant_id);
} else { } else {
sem_var = builder_->create<sem::Variable>( sem_var = builder_->create<sem::Variable>(
var, info->type, info->storage_class, var, info->type, info->storage_class, info->access);
info->access_control ? info->access_control->access_control()
: ast::AccessControl::kReadWrite);
} }
std::vector<const sem::VariableUser*> users; std::vector<const sem::VariableUser*> users;
@ -3274,12 +3256,12 @@ Resolver::VariableInfo::VariableInfo(const ast::Variable* decl,
sem::Type* ty, sem::Type* ty,
const std::string& tn, const std::string& tn,
ast::StorageClass sc, ast::StorageClass sc,
const ast::AccessControl* ac) ast::Access ac)
: declaration(decl), : declaration(decl),
type(ty), type(ty),
type_name(tn), type_name(tn),
storage_class(sc), storage_class(sc),
access_control(ac) {} access(ac) {}
Resolver::VariableInfo::~VariableInfo() = default; Resolver::VariableInfo::~VariableInfo() = default;

View File

@ -89,14 +89,14 @@ class Resolver {
sem::Type* type, sem::Type* type,
const std::string& type_name, const std::string& type_name,
ast::StorageClass storage_class, ast::StorageClass storage_class,
const ast::AccessControl* ac); ast::Access ac);
~VariableInfo(); ~VariableInfo();
ast::Variable const* const declaration; ast::Variable const* const declaration;
sem::Type* type; sem::Type* type;
std::string const type_name; std::string const type_name;
ast::StorageClass storage_class; ast::StorageClass storage_class;
ast::AccessControl const* const access_control; ast::Access const access;
std::vector<ast::IdentifierExpression*> users; std::vector<ast::IdentifierExpression*> users;
sem::BindingPoint binding_point; sem::BindingPoint binding_point;
}; };
@ -255,6 +255,7 @@ class Resolver {
const sem::Matrix* matrix_type); const sem::Matrix* matrix_type);
bool ValidateParameter(const VariableInfo* info); bool ValidateParameter(const VariableInfo* info);
bool ValidateReturn(const ast::ReturnStatement* ret); bool ValidateReturn(const ast::ReturnStatement* ret);
bool ValidateStorageTexture(const ast::StorageTexture* t);
bool ValidateStructure(const sem::Struct* str); bool ValidateStructure(const sem::Struct* str);
bool ValidateSwitch(const ast::SwitchStatement* s); bool ValidateSwitch(const ast::SwitchStatement* s);
bool ValidateVariable(const VariableInfo* info); bool ValidateVariable(const VariableInfo* info);
@ -394,7 +395,6 @@ class Resolver {
FunctionInfo* current_function_ = nullptr; FunctionInfo* current_function_ = nullptr;
sem::Statement* current_statement_ = nullptr; sem::Statement* current_statement_ = nullptr;
const ast::AccessControl* current_access_control_ = nullptr;
BlockAllocator<VariableInfo> variable_infos_; BlockAllocator<VariableInfo> variable_infos_;
BlockAllocator<FunctionInfo> function_infos_; BlockAllocator<FunctionInfo> function_infos_;
}; };

View File

@ -784,15 +784,15 @@ TEST_F(ResolverTest, Function_Parameters) {
TEST_F(ResolverTest, Function_RegisterInputOutputVariables) { TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
auto* s = Structure("S", {Member("m", ty.u32())}, auto* s = Structure("S", {Member("m", ty.u32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kRead, s);
auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput); auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput);
auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput); auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput);
auto* sb_var = Global("sb_var", a, ast::StorageClass::kStorage, auto* sb_var =
ast::DecorationList{ Global("sb_var", s, ast::StorageClass::kStorage, ast::Access::kRead,
create<ast::BindingDecoration>(0), ast::DecorationList{
create<ast::GroupDecoration>(0), create<ast::BindingDecoration>(0),
}); create<ast::GroupDecoration>(0),
});
auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup); auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate); auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
@ -823,15 +823,15 @@ TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) { TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
auto* s = Structure("S", {Member("m", ty.u32())}, auto* s = Structure("S", {Member("m", ty.u32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kRead, s);
auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput); auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput);
auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput); auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput);
auto* sb_var = Global("sb_var", a, ast::StorageClass::kStorage, auto* sb_var =
ast::DecorationList{ Global("sb_var", s, ast::StorageClass::kStorage, ast::Access::kRead,
create<ast::BindingDecoration>(0), ast::DecorationList{
create<ast::GroupDecoration>(0), create<ast::BindingDecoration>(0),
}); create<ast::GroupDecoration>(0),
});
auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup); auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate); auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
@ -1757,8 +1757,7 @@ TEST_F(ResolverTest, StorageClass_SetForSampler) {
TEST_F(ResolverTest, StorageClass_SetForTexture) { TEST_F(ResolverTest, StorageClass_SetForTexture) {
auto* t = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32()); auto* t = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
auto* ac = ty.access(ast::AccessControl::kRead, t); auto* var = Global("var", t,
auto* var = Global("var", ac,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -1780,6 +1779,22 @@ TEST_F(ResolverTest, StorageClass_DoesNotSetOnConst) {
EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kNone); EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kNone);
} }
TEST_F(ResolverTest, Access_SetForStorageBuffer) {
// [[block]] struct S { x : i32 };
// var<storage> g : S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())},
{create<ast::StructBlockDecoration>()});
auto* var = Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage,
ast::DecorationList{
create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0),
});
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_EQ(Sem().Get(var)->Access(), ast::Access::kRead);
}
TEST_F(ResolverTest, Function_EntryPoints_StageDecoration) { TEST_F(ResolverTest, Function_EntryPoints_StageDecoration) {
// fn b() {} // fn b() {}
// fn c() { b(); } // fn c() { b(); }

View File

@ -226,12 +226,6 @@ ast::Type* ast_alias(const ProgramBuilder::TypesBuilder& ty) {
return ty.builder->create<ast::TypeName>(name); return ty.builder->create<ast::TypeName>(name);
} }
template <create_ast_type_func_ptr create_type>
ast::Type* ast_access(const ProgramBuilder::TypesBuilder& ty) {
auto* type = create_type(ty);
return ty.access(ast::AccessControl::kRead, type);
}
inline sem::Type* sem_bool(const ProgramBuilder::TypesBuilder& ty) { inline sem::Type* sem_bool(const ProgramBuilder::TypesBuilder& ty) {
return ty.builder->create<sem::Bool>(); return ty.builder->create<sem::Bool>();
} }

View File

@ -46,7 +46,7 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferBool) {
EXPECT_EQ( EXPECT_EQ(
r()->error(), r()->error(),
R"(56:78 error: variables declared in the <storage> storage class must be of an [[access]] qualified structure type)"); R"(56:78 error: variables declared in the <storage> storage class must be of a structure type)");
} }
TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) { TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) {
@ -62,15 +62,15 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) {
EXPECT_EQ( EXPECT_EQ(
r()->error(), r()->error(),
R"(56:78 error: variables declared in the <storage> storage class must be of an [[access]] qualified structure type)"); R"(56:78 error: variables declared in the <storage> storage class must be of a structure type)");
} }
TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) { TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) {
// var<storage> g : [[access(read)]] array<S, 3>; // var<storage, read> g : array<S, 3>;
auto* s = Structure("S", {Member("a", ty.f32())}); auto* s = Structure("S", {Member("a", ty.f32())});
auto* a = ty.array(s, 3); auto* a = ty.array(s, 3);
auto* ac = ty.access(ast::AccessControl::kRead, a); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage,
Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kStorage, ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -80,12 +80,12 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) {
EXPECT_EQ( EXPECT_EQ(
r()->error(), r()->error(),
R"(56:78 error: variables declared in the <storage> storage class must be of an [[access]] qualified structure type)"); R"(56:78 error: variables declared in the <storage> storage class must be of a structure type)");
} }
TEST_F(ResolverStorageClassValidationTest, StorageBufferBoolAlias) { TEST_F(ResolverStorageClassValidationTest, StorageBufferBoolAlias) {
// type a = bool; // type a = bool;
// var<storage> g : [[access(read)]] a; // var<storage, read> g : a;
auto* a = ty.alias("a", ty.bool_()); auto* a = ty.alias("a", ty.bool_());
AST().AddConstructedType(a); AST().AddConstructedType(a);
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage,
@ -98,31 +98,15 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferBoolAlias) {
EXPECT_EQ( EXPECT_EQ(
r()->error(), r()->error(),
R"(56:78 error: variables declared in the <storage> storage class must be of an [[access]] qualified structure type)"); R"(56:78 error: variables declared in the <storage> storage class must be of a structure type)");
}
TEST_F(ResolverStorageClassValidationTest, StorageBufferNoAccessControl) {
// var<storage> g : S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage,
ast::DecorationList{
create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0),
});
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(56:78 error: variables declared in the <storage> storage class must be of an [[access]] qualified structure type)");
} }
TEST_F(ResolverStorageClassValidationTest, StorageBufferNoBlockDecoration) { TEST_F(ResolverStorageClassValidationTest, StorageBufferNoBlockDecoration) {
// struct S { x : i32 }; // struct S { x : i32 };
// var<storage> g : [[access(read)]] S; // var<storage, read> g : S;
auto* s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())}); auto* s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())});
auto* a = ty.access(ast::AccessControl::kRead, s); Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage,
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -138,11 +122,11 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferNoBlockDecoration) {
TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Basic) { TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Basic) {
// [[block]] struct S { x : i32 }; // [[block]] struct S { x : i32 };
// var<storage> g : [[access(read)]] S; // var<storage, read> g : S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kRead, s); Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage,
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -154,16 +138,15 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Basic) {
TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Aliases) { TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Aliases) {
// [[block]] struct S { x : i32 }; // [[block]] struct S { x : i32 };
// type a1 = S; // type a1 = S;
// type a2 = [[access(read)]] a1; // var<storage, read> g : a1;
// var<storage> g : a2;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a1 = ty.alias("a1", s); auto* a1 = ty.alias("a1", s);
AST().AddConstructedType(a1); AST().AddConstructedType(a1);
auto* ac = ty.access(ast::AccessControl::kRead, a1); auto* a2 = ty.alias("a2", a1);
auto* a2 = ty.alias("a2", ac);
AST().AddConstructedType(a2); AST().AddConstructedType(a2);
Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage, Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage,
ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -206,11 +189,10 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferPointer) {
} }
TEST_F(ResolverStorageClassValidationTest, UniformBufferArray) { TEST_F(ResolverStorageClassValidationTest, UniformBufferArray) {
// var<uniform> g : [[access(read)]] array<S, 3>; // var<uniform> g : array<S, 3>;
auto* s = Structure("S", {Member("a", ty.f32())}); auto* s = Structure("S", {Member("a", ty.f32())});
auto* a = ty.array(s, 3); auto* a = ty.array(s, 3);
auto* ac = ty.access(ast::AccessControl::kRead, a); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform,
Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kUniform,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -225,7 +207,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferArray) {
TEST_F(ResolverStorageClassValidationTest, UniformBufferBoolAlias) { TEST_F(ResolverStorageClassValidationTest, UniformBufferBoolAlias) {
// type a = bool; // type a = bool;
// var<uniform> g : [[access(read)]] a; // var<uniform> g : a;
auto* a = ty.alias("a", ty.bool_()); auto* a = ty.alias("a", ty.bool_());
AST().AddConstructedType(a); AST().AddConstructedType(a);
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform, Global(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform,

View File

@ -172,13 +172,12 @@ TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalArray) {
TEST_F(ResolverStorageClassUseTest, StructMultipleStorageClassUses) { TEST_F(ResolverStorageClassUseTest, StructMultipleStorageClassUses) {
auto* s = Structure("S", {Member("a", ty.f32())}, auto* s = Structure("S", {Member("a", ty.f32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kRead, s);
Global("x", s, ast::StorageClass::kUniform, Global("x", s, ast::StorageClass::kUniform,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
}); });
Global("y", ac, ast::StorageClass::kStorage, Global("y", s, ast::StorageClass::kStorage, ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(1), create<ast::BindingDecoration>(1),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),

View File

@ -66,10 +66,10 @@ TEST_F(ResolverTypeValidationTest, GlobalVariableWithStorageClass_Pass) {
TEST_F(ResolverTypeValidationTest, GlobalConstantWithStorageClass_Fail) { TEST_F(ResolverTypeValidationTest, GlobalConstantWithStorageClass_Fail) {
// const<in> global_var: f32; // const<in> global_var: f32;
AST().AddGlobalVariable( AST().AddGlobalVariable(create<ast::Variable>(
create<ast::Variable>(Source{{12, 34}}, Symbols().Register("global_var"), Source{{12, 34}}, Symbols().Register("global_var"),
ast::StorageClass::kInput, ty.f32(), true, ast::StorageClass::kInput, ast::Access::kUndefined, ty.f32(), true,
Expr(1.23f), ast::DecorationList{})); Expr(1.23f), ast::DecorationList{}));
EXPECT_FALSE(r()->Resolve()); EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), EXPECT_EQ(r()->error(),
@ -393,11 +393,9 @@ static constexpr Params cases[] = {
Params{ast_alias<ast_alias<ast_mat3x3<ast_alias<ast_alias<ast_f32>>>>>, Params{ast_alias<ast_alias<ast_mat3x3<ast_alias<ast_alias<ast_f32>>>>>,
sem_mat3x3<sem_f32>}, sem_mat3x3<sem_f32>},
Params{ast_alias<ast_access<ast_alias<ast_bool>>>, sem_bool}, Params{ast_alias<ast_alias<ast_bool>>, sem_bool},
Params{ast_alias<ast_access<ast_alias<ast_vec3<ast_access<ast_f32>>>>>, Params{ast_alias<ast_alias<ast_vec3<ast_f32>>>, sem_vec3<sem_f32>},
sem_vec3<sem_f32>}, Params{ast_alias<ast_alias<ast_mat3x3<ast_f32>>>, sem_mat3x3<sem_f32>},
Params{ast_alias<ast_access<ast_alias<ast_mat3x3<ast_access<ast_f32>>>>>,
sem_mat3x3<sem_f32>},
}; };
using CanonicalTest = ResolverTestWithParam<Params>; using CanonicalTest = ResolverTestWithParam<Params>;
@ -526,13 +524,13 @@ static constexpr DimensionParams Dimension_cases[] = {
using StorageTextureDimensionTest = ResolverTestWithParam<DimensionParams>; using StorageTextureDimensionTest = ResolverTestWithParam<DimensionParams>;
TEST_P(StorageTextureDimensionTest, All) { TEST_P(StorageTextureDimensionTest, All) {
// [[group(0), binding(0)]] // [[group(0), binding(0)]]
// var a : [[access(read)]] texture_storage_*<ru32int>; // var a : texture_storage_*<ru32int, read>;
auto& params = GetParam(); auto& params = GetParam();
auto* st = ty.storage_texture(params.dim, ast::ImageFormat::kR32Uint); auto* st = ty.storage_texture(Source{{12, 34}}, params.dim,
auto* ac = ty.access(ast::AccessControl::kRead, st); ast::ImageFormat::kR32Uint, ast::Access::kRead);
Global(Source{{12, 34}}, "a", ac, ast::StorageClass::kNone, nullptr, Global("a", st, ast::StorageClass::kNone,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -597,42 +595,41 @@ using StorageTextureFormatTest = ResolverTestWithParam<FormatParams>;
TEST_P(StorageTextureFormatTest, All) { TEST_P(StorageTextureFormatTest, All) {
auto& params = GetParam(); auto& params = GetParam();
// [[group(0), binding(0)]] // [[group(0), binding(0)]]
// var a : [[access(read)]] texture_storage_1d<*>; // var a : texture_storage_1d<*, read>;
// [[group(0), binding(1)]] // [[group(0), binding(1)]]
// var b : [[access(read)]] texture_storage_2d<*>; // var b : texture_storage_2d<*, read>;
// [[group(0), binding(2)]] // [[group(0), binding(2)]]
// var c : [[access(read)]] texture_storage_2d_array<*>; // var c : texture_storage_2d_array<*, read>;
// [[group(0), binding(3)]] // [[group(0), binding(3)]]
// var d : [[access(read)]] texture_storage_3d<*>; // var d : texture_storage_3d<*, read>;
auto* st_a = ty.storage_texture(ast::TextureDimension::k1d, params.format); auto* st_a = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d,
auto* ac_a = ty.access(ast::AccessControl::kRead, st_a); params.format, ast::Access::kRead);
Global(Source{{12, 34}}, "a", ac_a, ast::StorageClass::kNone, nullptr, Global("a", st_a, ast::StorageClass::kNone,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
}); });
auto* st_b = ty.storage_texture(ast::TextureDimension::k2d, params.format); auto* st_b = ty.storage_texture(ast::TextureDimension::k2d, params.format,
auto* ac_b = ty.access(ast::AccessControl::kRead, st_b); ast::Access::kRead);
Global("b", ac_b, ast::StorageClass::kNone, nullptr, Global("b", st_b, ast::StorageClass::kNone,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(1), create<ast::GroupDecoration>(1),
}); });
auto* st_c = auto* st_c = ty.storage_texture(ast::TextureDimension::k2dArray,
ty.storage_texture(ast::TextureDimension::k2dArray, params.format); params.format, ast::Access::kRead);
auto* ac_c = ty.access(ast::AccessControl::kRead, st_c); Global("c", st_c, ast::StorageClass::kNone,
Global("c", ac_c, ast::StorageClass::kNone, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(2), create<ast::GroupDecoration>(2),
}); });
auto* st_d = ty.storage_texture(ast::TextureDimension::k3d, params.format); auto* st_d = ty.storage_texture(ast::TextureDimension::k3d, params.format,
auto* ac_d = ty.access(ast::AccessControl::kRead, st_d); ast::Access::kRead);
Global("d", ac_d, ast::StorageClass::kNone, nullptr, Global("d", st_d, ast::StorageClass::kNone,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(3), create<ast::GroupDecoration>(3),
@ -652,16 +649,17 @@ INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
StorageTextureFormatTest, StorageTextureFormatTest,
testing::ValuesIn(format_cases)); testing::ValuesIn(format_cases));
using StorageTextureAccessControlTest = ResolverTest; using StorageTextureAccessTest = ResolverTest;
TEST_F(StorageTextureAccessControlTest, MissingAccessControl_Fail) { TEST_F(StorageTextureAccessTest, MissingAccess_Fail) {
// [[group(0), binding(0)]] // [[group(0), binding(0)]]
// var a : texture_storage_1d<ru32int>; // var a : texture_storage_1d<ru32int>;
auto* st = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d, auto* st =
ast::ImageFormat::kR32Uint); ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d,
ast::ImageFormat::kR32Uint, ast::Access::kUndefined);
Global("a", st, ast::StorageClass::kNone, nullptr, Global("a", st, ast::StorageClass::kNone,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -672,15 +670,15 @@ TEST_F(StorageTextureAccessControlTest, MissingAccessControl_Fail) {
"12:34 error: storage textures must have access control"); "12:34 error: storage textures must have access control");
} }
TEST_F(StorageTextureAccessControlTest, RWAccessControl_Fail) { TEST_F(StorageTextureAccessTest, RWAccess_Fail) {
// [[group(0), binding(0)]] // [[group(0), binding(0)]]
// var a : [[access(readwrite)]] texture_storage_1d<ru32int>; // var a : texture_storage_1d<ru32int, read_write>;
auto* st = ty.storage_texture(ast::TextureDimension::k1d, auto* st =
ast::ImageFormat::kR32Uint); ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d,
auto* ac = ty.access(ast::AccessControl::kReadWrite, st); ast::ImageFormat::kR32Uint, ast::Access::kReadWrite);
Global(Source{{12, 34}}, "a", ac, ast::StorageClass::kNone, nullptr, Global("a", st, ast::StorageClass::kNone, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -692,15 +690,14 @@ TEST_F(StorageTextureAccessControlTest, RWAccessControl_Fail) {
"write-only access"); "write-only access");
} }
TEST_F(StorageTextureAccessControlTest, ReadOnlyAccessControl_Pass) { TEST_F(StorageTextureAccessTest, ReadOnlyAccess_Pass) {
// [[group(0), binding(0)]] // [[group(0), binding(0)]]
// var a : [[access(read)]] texture_storage_1d<ru32int>; // var a : texture_storage_1d<ru32int, read>;
auto* st = ty.storage_texture(ast::TextureDimension::k1d, auto* st = ty.storage_texture(ast::TextureDimension::k1d,
ast::ImageFormat::kR32Uint); ast::ImageFormat::kR32Uint, ast::Access::kRead);
auto* ac = ty.access(ast::AccessControl::kRead, st);
Global("a", ac, ast::StorageClass::kNone, nullptr, Global("a", st, ast::StorageClass::kNone, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
@ -709,15 +706,15 @@ TEST_F(StorageTextureAccessControlTest, ReadOnlyAccessControl_Pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(r()->Resolve()) << r()->error();
} }
TEST_F(StorageTextureAccessControlTest, WriteOnlyAccessControl_Pass) { TEST_F(StorageTextureAccessTest, WriteOnlyAccess_Pass) {
// [[group(0), binding(0)]] // [[group(0), binding(0)]]
// var a : [[access(write)]] texture_storage_1d<ru32int>; // var a : texture_storage_1d<ru32int, write>;
auto* st = ty.storage_texture(ast::TextureDimension::k1d, auto* st =
ast::ImageFormat::kR32Uint); ty.storage_texture(ast::TextureDimension::k1d, ast::ImageFormat::kR32Uint,
auto* ac = ty.access(ast::AccessControl::kWrite, st); ast::Access::kWrite);
Global("a", ac, ast::StorageClass::kNone, nullptr, Global("a", st, ast::StorageClass::kNone, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),

View File

@ -23,12 +23,9 @@ namespace sem {
StorageTexture::StorageTexture(ast::TextureDimension dim, StorageTexture::StorageTexture(ast::TextureDimension dim,
ast::ImageFormat format, ast::ImageFormat format,
ast::AccessControl::Access access_control, ast::Access access,
sem::Type* subtype) sem::Type* subtype)
: Base(dim), : Base(dim), image_format_(format), access_(access), subtype_(subtype) {}
image_format_(format),
access_control_(access_control),
subtype_(subtype) {}
StorageTexture::StorageTexture(StorageTexture&&) = default; StorageTexture::StorageTexture(StorageTexture&&) = default;
@ -37,14 +34,14 @@ StorageTexture::~StorageTexture() = default;
std::string StorageTexture::type_name() const { std::string StorageTexture::type_name() const {
std::ostringstream out; std::ostringstream out;
out << "__storage_texture_" << dim() << "_" << image_format_ << "_" out << "__storage_texture_" << dim() << "_" << image_format_ << "_"
<< access_control_; << access_;
return out.str(); return out.str();
} }
std::string StorageTexture::FriendlyName(const SymbolTable&) const { std::string StorageTexture::FriendlyName(const SymbolTable&) const {
std::ostringstream out; std::ostringstream out;
out << "texture_storage_" << dim() << "<" << image_format_ << ", " out << "texture_storage_" << dim() << "<" << image_format_ << ", " << access_
<< access_control_ << ">"; << ">";
return out.str(); return out.str();
} }

View File

@ -17,7 +17,7 @@
#include <string> #include <string>
#include "src/ast/access_control.h" #include "src/ast/access.h"
#include "src/ast/storage_texture.h" #include "src/ast/storage_texture.h"
#include "src/sem/texture_type.h" #include "src/sem/texture_type.h"
@ -32,11 +32,11 @@ class StorageTexture : public Castable<StorageTexture, Texture> {
/// Constructor /// Constructor
/// @param dim the dimensionality of the texture /// @param dim the dimensionality of the texture
/// @param format the image format of the texture /// @param format the image format of the texture
/// @param access_control the access control type of the texture /// @param access the access control type of the texture
/// @param subtype the storage subtype. Use SubtypeFor() to calculate this. /// @param subtype the storage subtype. Use SubtypeFor() to calculate this.
StorageTexture(ast::TextureDimension dim, StorageTexture(ast::TextureDimension dim,
ast::ImageFormat format, ast::ImageFormat format,
ast::AccessControl::Access access_control, ast::Access access,
sem::Type* subtype); sem::Type* subtype);
/// Move constructor /// Move constructor
@ -50,7 +50,7 @@ class StorageTexture : public Castable<StorageTexture, Texture> {
ast::ImageFormat image_format() const { return image_format_; } ast::ImageFormat image_format() const { return image_format_; }
/// @returns the access control /// @returns the access control
ast::AccessControl::Access access_control() const { return access_control_; } ast::Access access() const { return access_; }
/// @returns the name for this type /// @returns the name for this type
std::string type_name() const override; std::string type_name() const override;
@ -67,7 +67,7 @@ class StorageTexture : public Castable<StorageTexture, Texture> {
private: private:
ast::ImageFormat const image_format_; ast::ImageFormat const image_format_;
ast::AccessControl::Access const access_control_; ast::Access const access_;
Type* const subtype_; Type* const subtype_;
}; };

View File

@ -30,7 +30,7 @@ TEST_F(StorageTextureTest, Dim) {
StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Float, Types()); StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Float, Types());
auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray, auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::AccessControl::kReadWrite, subtype); ast::Access::kReadWrite, subtype);
EXPECT_EQ(s->dim(), ast::TextureDimension::k2dArray); EXPECT_EQ(s->dim(), ast::TextureDimension::k2dArray);
} }
@ -39,7 +39,7 @@ TEST_F(StorageTextureTest, Format) {
StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Float, Types()); StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Float, Types());
auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray, auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::AccessControl::kReadWrite, subtype); ast::Access::kReadWrite, subtype);
EXPECT_EQ(s->image_format(), ast::ImageFormat::kRgba32Float); EXPECT_EQ(s->image_format(), ast::ImageFormat::kRgba32Float);
} }
@ -48,7 +48,7 @@ TEST_F(StorageTextureTest, TypeName) {
StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Float, Types()); StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Float, Types());
auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray, auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::AccessControl::kReadWrite, subtype); ast::Access::kReadWrite, subtype);
EXPECT_EQ(s->type_name(), EXPECT_EQ(s->type_name(),
"__storage_texture_2d_array_rgba32float_read_write"); "__storage_texture_2d_array_rgba32float_read_write");
} }
@ -58,7 +58,7 @@ TEST_F(StorageTextureTest, FriendlyName) {
StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Float, Types()); StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Float, Types());
auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray, auto* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::AccessControl::kReadWrite, subtype); ast::Access::kReadWrite, subtype);
EXPECT_EQ(s->FriendlyName(Symbols()), EXPECT_EQ(s->FriendlyName(Symbols()),
"texture_storage_2d_array<rgba32float, read_write>"); "texture_storage_2d_array<rgba32float, read_write>");
} }
@ -68,7 +68,7 @@ TEST_F(StorageTextureTest, F32) {
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Float, Types()); sem::StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Float, Types());
Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray, Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::ImageFormat::kRgba32Float, ast::ImageFormat::kRgba32Float,
ast::AccessControl::kReadWrite, subtype); ast::Access::kReadWrite, subtype);
auto program = Build(); auto program = Build();
@ -83,7 +83,7 @@ TEST_F(StorageTextureTest, U32) {
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kRg32Uint, Types()); sem::StorageTexture::SubtypeFor(ast::ImageFormat::kRg32Uint, Types());
Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray, Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::ImageFormat::kRg32Uint, ast::ImageFormat::kRg32Uint,
ast::AccessControl::kReadWrite, subtype); ast::Access::kReadWrite, subtype);
auto program = Build(); auto program = Build();
@ -98,7 +98,7 @@ TEST_F(StorageTextureTest, I32) {
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Sint, Types()); sem::StorageTexture::SubtypeFor(ast::ImageFormat::kRgba32Sint, Types());
Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray, Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray,
ast::ImageFormat::kRgba32Sint, ast::ImageFormat::kRgba32Sint,
ast::AccessControl::kReadWrite, subtype); ast::Access::kReadWrite, subtype);
auto program = Build(); auto program = Build();

View File

@ -26,11 +26,11 @@ namespace sem {
Variable::Variable(const ast::Variable* declaration, Variable::Variable(const ast::Variable* declaration,
const sem::Type* type, const sem::Type* type,
ast::StorageClass storage_class, ast::StorageClass storage_class,
ast::AccessControl::Access access_control) ast::Access access)
: declaration_(declaration), : declaration_(declaration),
type_(type), type_(type),
storage_class_(storage_class), storage_class_(storage_class),
access_control_(access_control), access_(access),
is_pipeline_constant_(false) {} is_pipeline_constant_(false) {}
Variable::Variable(const ast::Variable* declaration, Variable::Variable(const ast::Variable* declaration,
@ -39,7 +39,7 @@ Variable::Variable(const ast::Variable* declaration,
: declaration_(declaration), : declaration_(declaration),
type_(type), type_(type),
storage_class_(ast::StorageClass::kNone), storage_class_(ast::StorageClass::kNone),
access_control_(ast::AccessControl::kReadWrite), access_(ast::Access::kReadWrite),
is_pipeline_constant_(true), is_pipeline_constant_(true),
constant_id_(constant_id) {} constant_id_(constant_id) {}

View File

@ -17,7 +17,7 @@
#include <vector> #include <vector>
#include "src/ast/access_control.h" #include "src/ast/access.h"
#include "src/ast/storage_class.h" #include "src/ast/storage_class.h"
#include "src/sem/expression.h" #include "src/sem/expression.h"
@ -42,11 +42,11 @@ class Variable : public Castable<Variable, Node> {
/// @param declaration the AST declaration node /// @param declaration the AST declaration node
/// @param type the variable type /// @param type the variable type
/// @param storage_class the variable storage class /// @param storage_class the variable storage class
/// @param access_control the variable access control type /// @param access the variable access control type
Variable(const ast::Variable* declaration, Variable(const ast::Variable* declaration,
const sem::Type* type, const sem::Type* type,
ast::StorageClass storage_class, ast::StorageClass storage_class,
ast::AccessControl::Access access_control); ast::Access access);
/// Constructor for overridable pipeline constants /// Constructor for overridable pipeline constants
/// @param declaration the AST declaration node /// @param declaration the AST declaration node
@ -69,7 +69,7 @@ class Variable : public Castable<Variable, Node> {
ast::StorageClass StorageClass() const { return storage_class_; } ast::StorageClass StorageClass() const { return storage_class_; }
/// @returns the access control for the variable /// @returns the access control for the variable
ast::AccessControl::Access AccessControl() const { return access_control_; } ast::Access Access() const { return access_; }
/// @returns the expressions that use the variable /// @returns the expressions that use the variable
const std::vector<const VariableUser*>& Users() const { return users_; } const std::vector<const VariableUser*>& Users() const { return users_; }
@ -87,7 +87,7 @@ class Variable : public Castable<Variable, Node> {
const ast::Variable* const declaration_; const ast::Variable* const declaration_;
const sem::Type* const type_; const sem::Type* const type_;
ast::StorageClass const storage_class_; ast::StorageClass const storage_class_;
ast::AccessControl::Access const access_control_; ast::Access const access_;
std::vector<const VariableUser*> users_; std::vector<const VariableUser*> users_;
const bool is_pipeline_constant_; const bool is_pipeline_constant_;
const uint16_t constant_id_ = 0; const uint16_t constant_id_ = 0;

View File

@ -112,13 +112,12 @@ Output BindingRemapper::Run(const Program* in, const DataMap& datamap) {
// Replace any access controls. // Replace any access controls.
auto ac_it = remappings->access_controls.find(from); auto ac_it = remappings->access_controls.find(from);
if (ac_it != remappings->access_controls.end()) { if (ac_it != remappings->access_controls.end()) {
ast::AccessControl::Access ac = ac_it->second; ast::Access ac = ac_it->second;
auto* ty = in->Sem().Get(var)->Type()->UnwrapRef(); auto* ty = in->Sem().Get(var)->Type()->UnwrapRef();
ast::Type* inner_ty = CreateASTTypeFor(&ctx, ty); ast::Type* inner_ty = CreateASTTypeFor(&ctx, ty);
auto* new_ty = ctx.dst->create<ast::AccessControl>(ac, inner_ty);
auto* new_var = ctx.dst->create<ast::Variable>( auto* new_var = ctx.dst->create<ast::Variable>(
ctx.Clone(var->source()), ctx.Clone(var->symbol()), ctx.Clone(var->source()), ctx.Clone(var->symbol()),
var->declared_storage_class(), new_ty, var->is_const(), var->declared_storage_class(), ac, inner_ty, var->is_const(),
ctx.Clone(var->constructor()), ctx.Clone(var->decorations())); ctx.Clone(var->constructor()), ctx.Clone(var->decorations()));
ctx.Replace(var, new_var); ctx.Replace(var, new_var);
} }

View File

@ -17,7 +17,7 @@
#include <unordered_map> #include <unordered_map>
#include "src/ast/access_control.h" #include "src/ast/access.h"
#include "src/sem/binding_point.h" #include "src/sem/binding_point.h"
#include "src/transform/transform.h" #include "src/transform/transform.h"
@ -35,8 +35,7 @@ class BindingRemapper : public Transform {
using BindingPoints = std::unordered_map<BindingPoint, BindingPoint>; using BindingPoints = std::unordered_map<BindingPoint, BindingPoint>;
/// AccessControls is a map of old binding point to new access control /// AccessControls is a map of old binding point to new access control
using AccessControls = using AccessControls = std::unordered_map<BindingPoint, ast::Access>;
std::unordered_map<BindingPoint, ast::AccessControl::Access>;
/// Remappings is consumed by the BindingRemapper transform. /// Remappings is consumed by the BindingRemapper transform.
/// Data holds information about shader usage and constant buffer offsets. /// Data holds information about shader usage and constant buffer offsets.

View File

@ -30,9 +30,9 @@ TEST_F(BindingRemapperTest, NoRemappings) {
struct S { struct S {
}; };
[[group(2), binding(1)]] var<storage> a : [[access(read)]] S; [[group(2), binding(1)]] var<storage, read> a : S;
[[group(3), binding(2)]] var<storage> b : [[access(read)]] S; [[group(3), binding(2)]] var<storage, read> b : S;
[[stage(compute)]] [[stage(compute)]]
fn f() { fn f() {
@ -55,9 +55,9 @@ TEST_F(BindingRemapperTest, RemapBindingPoints) {
struct S { struct S {
}; };
[[group(2), binding(1)]] var<storage> a : [[access(read)]] S; [[group(2), binding(1)]] var<storage, read> a : S;
[[group(3), binding(2)]] var<storage> b : [[access(read)]] S; [[group(3), binding(2)]] var<storage, read> b : S;
[[stage(compute)]] [[stage(compute)]]
fn f() { fn f() {
@ -69,9 +69,9 @@ fn f() {
struct S { struct S {
}; };
[[group(1), binding(2)]] var<storage> a : [[access(read)]] S; [[group(1), binding(2)]] var<storage, read> a : S;
[[group(3), binding(2)]] var<storage> b : [[access(read)]] S; [[group(3), binding(2)]] var<storage, read> b : S;
[[stage(compute)]] [[stage(compute)]]
fn f() { fn f() {
@ -97,11 +97,11 @@ TEST_F(BindingRemapperTest, RemapAccessControls) {
struct S { struct S {
}; };
[[group(2), binding(1)]] var<storage> a : [[access(read)]] S; [[group(2), binding(1)]] var<storage, read> a : S;
[[group(3), binding(2)]] var<storage> b : [[access(write)]] S; [[group(3), binding(2)]] var<storage, write> b : S;
[[group(4), binding(3)]] var<storage> c : [[access(read)]] S; [[group(4), binding(3)]] var<storage, read> c : S;
[[stage(compute)]] [[stage(compute)]]
fn f() { fn f() {
@ -113,11 +113,11 @@ fn f() {
struct S { struct S {
}; };
[[group(2), binding(1)]] var<storage> a : [[access(write)]] S; [[group(2), binding(1)]] var<storage, write> a : S;
[[group(3), binding(2)]] var<storage> b : [[access(write)]] S; [[group(3), binding(2)]] var<storage, write> b : S;
[[group(4), binding(3)]] var<storage> c : [[access(read)]] S; [[group(4), binding(3)]] var<storage, read> c : S;
[[stage(compute)]] [[stage(compute)]]
fn f() { fn f() {
@ -128,9 +128,9 @@ fn f() {
data.Add<BindingRemapper::Remappings>( data.Add<BindingRemapper::Remappings>(
BindingRemapper::BindingPoints{}, BindingRemapper::BindingPoints{},
BindingRemapper::AccessControls{ BindingRemapper::AccessControls{
{{2, 1}, ast::AccessControl::kWrite}, // Modify access control {{2, 1}, ast::Access::kWrite}, // Modify access control
// Keep [[group(3), binding(2)]] as is // Keep [[group(3), binding(2)]] as is
{{4, 3}, ast::AccessControl::kRead}, // Add access control {{4, 3}, ast::Access::kRead}, // Add access control
}); });
auto got = Run<BindingRemapper>(src, data); auto got = Run<BindingRemapper>(src, data);
@ -145,9 +145,9 @@ TEST_F(BindingRemapperTest, DISABLED_RemapAccessControlsWithAliases) {
struct S { struct S {
}; };
type ReadOnlyS = [[access(read)]] S; type, read ReadOnlyS = S;
type WriteOnlyS = [[access(write)]] S; type, write WriteOnlyS = S;
type A = S; type A = S;
@ -167,17 +167,17 @@ fn f() {
struct S { struct S {
}; };
type ReadOnlyS = [[access(read)]] S; type, read ReadOnlyS = S;
type WriteOnlyS = [[access(write)]] S; type, write WriteOnlyS = S;
type A = S; type A = S;
[[group(2), binding(1)]] var<storage> a : [[access(write)]] S; [[group(2), binding(1)]] var<storage, write> a : S;
[[group(3), binding(2)]] var<storage> b : WriteOnlyS; [[group(3), binding(2)]] var<storage> b : WriteOnlyS;
[[group(4), binding(3)]] var<storage> c : [[access(write)]] S; [[group(4), binding(3)]] var<storage, write> c : S;
[[stage(compute)]] [[stage(compute)]]
fn f() { fn f() {
@ -188,9 +188,9 @@ fn f() {
data.Add<BindingRemapper::Remappings>( data.Add<BindingRemapper::Remappings>(
BindingRemapper::BindingPoints{}, BindingRemapper::BindingPoints{},
BindingRemapper::AccessControls{ BindingRemapper::AccessControls{
{{2, 1}, ast::AccessControl::kWrite}, // Modify access control {{2, 1}, ast::Access::kWrite}, // Modify access control
// Keep [[group(3), binding(2)]] as is // Keep [[group(3), binding(2)]] as is
{{4, 3}, ast::AccessControl::kRead}, // Add access control {{4, 3}, ast::Access::kRead}, // Add access control
}); });
auto got = Run<BindingRemapper>(src, data); auto got = Run<BindingRemapper>(src, data);
@ -203,9 +203,9 @@ TEST_F(BindingRemapperTest, RemapAll) {
struct S { struct S {
}; };
[[group(2), binding(1)]] var<storage> a : [[access(read)]] S; [[group(2), binding(1)]] var<storage, read> a : S;
[[group(3), binding(2)]] var<storage> b : [[access(read)]] S; [[group(3), binding(2)]] var<storage, read> b : S;
[[stage(compute)]] [[stage(compute)]]
fn f() { fn f() {
@ -217,9 +217,9 @@ fn f() {
struct S { struct S {
}; };
[[group(4), binding(5)]] var<storage> a : [[access(write)]] S; [[group(4), binding(5)]] var<storage, write> a : S;
[[group(6), binding(7)]] var<storage> b : [[access(write)]] S; [[group(6), binding(7)]] var<storage, write> b : S;
[[stage(compute)]] [[stage(compute)]]
fn f() { fn f() {
@ -233,8 +233,8 @@ fn f() {
{{3, 2}, {6, 7}}, {{3, 2}, {6, 7}},
}, },
BindingRemapper::AccessControls{ BindingRemapper::AccessControls{
{{2, 1}, ast::AccessControl::kWrite}, {{2, 1}, ast::Access::kWrite},
{{3, 2}, ast::AccessControl::kWrite}, {{3, 2}, ast::Access::kWrite},
}); });
auto got = Run<BindingRemapper>(src, data); auto got = Run<BindingRemapper>(src, data);
@ -248,13 +248,13 @@ struct S {
i : i32; i : i32;
}; };
[[group(2), binding(1)]] var<storage> a : [[access(read)]] S; [[group(2), binding(1)]] var<storage, read> a : S;
[[group(3), binding(2)]] var<storage> b : [[access(read)]] S; [[group(3), binding(2)]] var<storage, read> b : S;
[[group(4), binding(3)]] var<storage> c : [[access(read)]] S; [[group(4), binding(3)]] var<storage, read> c : S;
[[group(5), binding(4)]] var<storage> d : [[access(read)]] S; [[group(5), binding(4)]] var<storage, read> d : S;
[[stage(compute)]] [[stage(compute)]]
fn f() { fn f() {
@ -268,13 +268,13 @@ struct S {
i : i32; i : i32;
}; };
[[internal(disable_validation__binding_point_collision), group(1), binding(1)]] var<storage> a : [[access(read)]] S; [[internal(disable_validation__binding_point_collision), group(1), binding(1)]] var<storage, read> a : S;
[[internal(disable_validation__binding_point_collision), group(1), binding(1)]] var<storage> b : [[access(read)]] S; [[internal(disable_validation__binding_point_collision), group(1), binding(1)]] var<storage, read> b : S;
[[internal(disable_validation__binding_point_collision), group(5), binding(4)]] var<storage> c : [[access(read)]] S; [[internal(disable_validation__binding_point_collision), group(5), binding(4)]] var<storage, read> c : S;
[[internal(disable_validation__binding_point_collision), group(5), binding(4)]] var<storage> d : [[access(read)]] S; [[internal(disable_validation__binding_point_collision), group(5), binding(4)]] var<storage, read> d : S;
[[stage(compute)]] [[stage(compute)]]
fn f() { fn f() {
@ -302,13 +302,13 @@ struct S {
i : i32; i : i32;
}; };
[[group(2), binding(1)]] var<storage> a : [[access(read)]] S; [[group(2), binding(1)]] var<storage, read> a : S;
[[group(3), binding(2)]] var<storage> b : [[access(read)]] S; [[group(3), binding(2)]] var<storage, read> b : S;
[[group(4), binding(3)]] var<storage> c : [[access(read)]] S; [[group(4), binding(3)]] var<storage, read> c : S;
[[group(5), binding(4)]] var<storage> d : [[access(read)]] S; [[group(5), binding(4)]] var<storage, read> d : S;
[[stage(compute)]] [[stage(compute)]]
fn f1() { fn f1() {
@ -327,13 +327,13 @@ struct S {
i : i32; i : i32;
}; };
[[group(1), binding(1)]] var<storage> a : [[access(read)]] S; [[group(1), binding(1)]] var<storage, read> a : S;
[[group(1), binding(1)]] var<storage> b : [[access(read)]] S; [[group(1), binding(1)]] var<storage, read> b : S;
[[group(5), binding(4)]] var<storage> c : [[access(read)]] S; [[group(5), binding(4)]] var<storage, read> c : S;
[[group(5), binding(4)]] var<storage> d : [[access(read)]] S; [[group(5), binding(4)]] var<storage, read> d : S;
[[stage(compute)]] [[stage(compute)]]
fn f1() { fn f1() {
@ -365,8 +365,8 @@ TEST_F(BindingRemapperTest, NoData) {
struct S { struct S {
}; };
[[group(2), binding(1)]] var<storage> a : [[access(read)]] S; [[group(2), binding(1)]] var<storage, read> a : S;
[[group(3), binding(2)]] var<storage> b : [[access(read)]] S; [[group(3), binding(2)]] var<storage, read> b : S;
[[stage(compute)]] [[stage(compute)]]
fn f() {} fn f() {}

View File

@ -540,7 +540,7 @@ struct S {
a : f32; a : f32;
b : array<f32>; b : array<f32>;
}; };
[[group(0), binding(0)]] var<storage> s : [[access(read)]] S; [[group(0), binding(0)]] var<storage, read> s : S;
fn f() { fn f() {
var d : f32 = s.b[25]; var d : f32 = s.b[25];
@ -554,7 +554,7 @@ struct S {
b : array<f32>; b : array<f32>;
}; };
[[group(0), binding(0)]] var<storage> s : [[access(read)]] S; [[group(0), binding(0)]] var<storage, read> s : S;
fn f() { fn f() {
var d : f32 = s.b[min(u32(25), (arrayLength(s.b) - 1u))]; var d : f32 = s.b[min(u32(25), (arrayLength(s.b) - 1u))];
@ -601,7 +601,7 @@ struct S {
b : array<f32>; b : array<f32>;
}; };
[[group(0), binding(0)]] var<storage> s : [[access(read)]] S; [[group(0), binding(0)]] var<storage, read> s : S;
let c : u32 = 1u; let c : u32 = 1u;
@ -619,7 +619,7 @@ struct S {
b : array<f32>; b : array<f32>;
}; };
[[group(0), binding(0)]] var<storage> s : [[access(read)]] S; [[group(0), binding(0)]] var<storage, read> s : S;
let c : u32 = 1u; let c : u32 = 1u;

View File

@ -91,7 +91,8 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) {
// in order for HLSL to emit this as a ByteAddressBuffer. // in order for HLSL to emit this as a ByteAddressBuffer.
ctx.dst->create<ast::Variable>( ctx.dst->create<ast::Variable>(
ctx.dst->Sym("buffer"), ast::StorageClass::kStorage, ctx.dst->Sym("buffer"), ast::StorageClass::kStorage,
buffer_typename, true, nullptr, ast::DecorationList{}), ast::Access::kUndefined, buffer_typename, true, nullptr,
ast::DecorationList{}),
ctx.dst->Param("result", ctx.dst->Param("result",
ctx.dst->ty.pointer(ctx.dst->ty.u32(), ctx.dst->ty.pointer(ctx.dst->ty.u32(),
ast::StorageClass::kFunction)), ast::StorageClass::kFunction)),

View File

@ -30,7 +30,7 @@ struct SB {
arr : array<i32>; arr : array<i32>;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read)]] SB; [[group(0), binding(0)]] var<storage, read> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -48,7 +48,7 @@ struct SB {
[[internal(intrinsic_buffer_size)]] [[internal(intrinsic_buffer_size)]]
fn tint_symbol(buffer : SB, result : ptr<function, u32>) fn tint_symbol(buffer : SB, result : ptr<function, u32>)
[[group(0), binding(0)]] var<storage> sb : [[access(read)]] SB; [[group(0), binding(0)]] var<storage, read> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -72,7 +72,7 @@ struct SB {
arr : array<i32>; arr : array<i32>;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read)]] SB; [[group(0), binding(0)]] var<storage, read> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -92,7 +92,7 @@ struct SB {
[[internal(intrinsic_buffer_size)]] [[internal(intrinsic_buffer_size)]]
fn tint_symbol(buffer : SB, result : ptr<function, u32>) fn tint_symbol(buffer : SB, result : ptr<function, u32>)
[[group(0), binding(0)]] var<storage> sb : [[access(read)]] SB; [[group(0), binding(0)]] var<storage, read> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -119,7 +119,7 @@ struct SB {
arr : [[stride(64)]] array<i32>; arr : [[stride(64)]] array<i32>;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read)]] SB; [[group(0), binding(0)]] var<storage, read> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -138,7 +138,7 @@ struct SB {
[[internal(intrinsic_buffer_size)]] [[internal(intrinsic_buffer_size)]]
fn tint_symbol(buffer : SB, result : ptr<function, u32>) fn tint_symbol(buffer : SB, result : ptr<function, u32>)
[[group(0), binding(0)]] var<storage> sb : [[access(read)]] SB; [[group(0), binding(0)]] var<storage, read> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -162,7 +162,7 @@ struct SB {
arr : array<i32>; arr : array<i32>;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read)]] SB; [[group(0), binding(0)]] var<storage, read> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -186,7 +186,7 @@ struct SB {
[[internal(intrinsic_buffer_size)]] [[internal(intrinsic_buffer_size)]]
fn tint_symbol(buffer : SB, result : ptr<function, u32>) fn tint_symbol(buffer : SB, result : ptr<function, u32>)
[[group(0), binding(0)]] var<storage> sb : [[access(read)]] SB; [[group(0), binding(0)]] var<storage, read> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -225,9 +225,9 @@ struct SB2 {
arr2 : array<vec4<f32>>; arr2 : array<vec4<f32>>;
}; };
[[group(0), binding(0)]] var<storage> sb1 : [[access(read)]] SB1; [[group(0), binding(0)]] var<storage, read> sb1 : SB1;
[[group(0), binding(1)]] var<storage> sb2 : [[access(read)]] SB2; [[group(0), binding(1)]] var<storage, read> sb2 : SB2;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -256,9 +256,9 @@ struct SB2 {
[[internal(intrinsic_buffer_size)]] [[internal(intrinsic_buffer_size)]]
fn tint_symbol_3(buffer : SB2, result : ptr<function, u32>) fn tint_symbol_3(buffer : SB2, result : ptr<function, u32>)
[[group(0), binding(0)]] var<storage> sb1 : [[access(read)]] SB1; [[group(0), binding(0)]] var<storage, read> sb1 : SB1;
[[group(0), binding(1)]] var<storage> sb2 : [[access(read)]] SB2; [[group(0), binding(1)]] var<storage, read> sb2 : SB2;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {

View File

@ -360,17 +360,6 @@ struct Store {
StorageBufferAccess target; // The target for the write StorageBufferAccess target; // The target for the write
}; };
ast::Type* MaybeCreateASTAccessControl(CloneContext* ctx,
const sem::VariableUser* var_user,
ast::Type* ty) {
if (var_user &&
var_user->Variable()->StorageClass() == ast::StorageClass::kStorage) {
return ctx->dst->create<ast::AccessControl>(
var_user->Variable()->AccessControl(), ty);
}
return ty;
}
} // namespace } // namespace
/// State holds the current transform state /// State holds the current transform state
@ -431,14 +420,14 @@ struct DecomposeStorageAccess::State {
const sem::VariableUser* var_user) { const sem::VariableUser* var_user) {
return utils::GetOrCreate(load_funcs, TypePair{buf_ty, el_ty}, [&] { return utils::GetOrCreate(load_funcs, TypePair{buf_ty, el_ty}, [&] {
auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty); auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty);
buf_ast_ty = MaybeCreateASTAccessControl(&ctx, var_user, buf_ast_ty);
ast::VariableList params = { ast::VariableList params = {
// Note: The buffer parameter requires the kStorage StorageClass in // Note: The buffer parameter requires the kStorage StorageClass in
// order for HLSL to emit this as a ByteAddressBuffer. // order for HLSL to emit this as a ByteAddressBuffer.
ctx.dst->create<ast::Variable>( ctx.dst->create<ast::Variable>(
ctx.dst->Sym("buffer"), ast::StorageClass::kStorage, buf_ast_ty, ctx.dst->Sym("buffer"), ast::StorageClass::kStorage,
true, nullptr, ast::DecorationList{}), var_user->Variable()->Access(), buf_ast_ty, true, nullptr,
ast::DecorationList{}),
ctx.dst->Param("offset", ctx.dst->ty.u32()), ctx.dst->Param("offset", ctx.dst->ty.u32()),
}; };
@ -507,14 +496,14 @@ struct DecomposeStorageAccess::State {
const sem::VariableUser* var_user) { const sem::VariableUser* var_user) {
return utils::GetOrCreate(store_funcs, TypePair{buf_ty, el_ty}, [&] { return utils::GetOrCreate(store_funcs, TypePair{buf_ty, el_ty}, [&] {
auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty); auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty);
buf_ast_ty = MaybeCreateASTAccessControl(&ctx, var_user, buf_ast_ty);
auto* el_ast_ty = CreateASTTypeFor(&ctx, el_ty); auto* el_ast_ty = CreateASTTypeFor(&ctx, el_ty);
ast::VariableList params{ ast::VariableList params{
// Note: The buffer parameter requires the kStorage StorageClass in // Note: The buffer parameter requires the kStorage StorageClass in
// order for HLSL to emit this as a ByteAddressBuffer. // order for HLSL to emit this as a ByteAddressBuffer.
ctx.dst->create<ast::Variable>( ctx.dst->create<ast::Variable>(
ctx.dst->Sym("buffer"), ast::StorageClass::kStorage, buf_ast_ty, ctx.dst->Sym("buffer"), ast::StorageClass::kStorage,
true, nullptr, ast::DecorationList{}), var_user->Variable()->Access(), buf_ast_ty, true, nullptr,
ast::DecorationList{}),
ctx.dst->Param("offset", ctx.dst->ty.u32()), ctx.dst->Param("offset", ctx.dst->ty.u32()),
ctx.dst->Param("value", el_ast_ty), ctx.dst->Param("value", el_ast_ty),
}; };

View File

@ -50,7 +50,7 @@ struct SB {
v : array<vec3<f32>, 2>; v : array<vec3<f32>, 2>;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -107,82 +107,82 @@ struct SB {
}; };
[[internal(intrinsic_load_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol(buffer : [[access(read_write)]] SB, offset : u32) -> i32 fn tint_symbol(buffer : SB, offset : u32) -> i32
[[internal(intrinsic_load_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_1(buffer : [[access(read_write)]] SB, offset : u32) -> u32 fn tint_symbol_1(buffer : SB, offset : u32) -> u32
[[internal(intrinsic_load_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_2(buffer : [[access(read_write)]] SB, offset : u32) -> f32 fn tint_symbol_2(buffer : SB, offset : u32) -> f32
[[internal(intrinsic_load_vec2_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec2_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_3(buffer : [[access(read_write)]] SB, offset : u32) -> vec2<i32> fn tint_symbol_3(buffer : SB, offset : u32) -> vec2<i32>
[[internal(intrinsic_load_vec2_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec2_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_4(buffer : [[access(read_write)]] SB, offset : u32) -> vec2<u32> fn tint_symbol_4(buffer : SB, offset : u32) -> vec2<u32>
[[internal(intrinsic_load_vec2_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec2_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_5(buffer : [[access(read_write)]] SB, offset : u32) -> vec2<f32> fn tint_symbol_5(buffer : SB, offset : u32) -> vec2<f32>
[[internal(intrinsic_load_vec3_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec3_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_6(buffer : [[access(read_write)]] SB, offset : u32) -> vec3<i32> fn tint_symbol_6(buffer : SB, offset : u32) -> vec3<i32>
[[internal(intrinsic_load_vec3_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec3_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_7(buffer : [[access(read_write)]] SB, offset : u32) -> vec3<u32> fn tint_symbol_7(buffer : SB, offset : u32) -> vec3<u32>
[[internal(intrinsic_load_vec3_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec3_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_8(buffer : [[access(read_write)]] SB, offset : u32) -> vec3<f32> fn tint_symbol_8(buffer : SB, offset : u32) -> vec3<f32>
[[internal(intrinsic_load_vec4_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec4_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_9(buffer : [[access(read_write)]] SB, offset : u32) -> vec4<i32> fn tint_symbol_9(buffer : SB, offset : u32) -> vec4<i32>
[[internal(intrinsic_load_vec4_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec4_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_10(buffer : [[access(read_write)]] SB, offset : u32) -> vec4<u32> fn tint_symbol_10(buffer : SB, offset : u32) -> vec4<u32>
[[internal(intrinsic_load_vec4_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec4_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_11(buffer : [[access(read_write)]] SB, offset : u32) -> vec4<f32> fn tint_symbol_11(buffer : SB, offset : u32) -> vec4<f32>
fn tint_symbol_12(buffer : [[access(read_write)]] SB, offset : u32) -> mat2x2<f32> { fn tint_symbol_12(buffer : SB, offset : u32) -> mat2x2<f32> {
return mat2x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u))); return mat2x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)));
} }
fn tint_symbol_13(buffer : [[access(read_write)]] SB, offset : u32) -> mat2x3<f32> { fn tint_symbol_13(buffer : SB, offset : u32) -> mat2x3<f32> {
return mat2x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u))); return mat2x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)));
} }
fn tint_symbol_14(buffer : [[access(read_write)]] SB, offset : u32) -> mat2x4<f32> { fn tint_symbol_14(buffer : SB, offset : u32) -> mat2x4<f32> {
return mat2x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u))); return mat2x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)));
} }
fn tint_symbol_15(buffer : [[access(read_write)]] SB, offset : u32) -> mat3x2<f32> { fn tint_symbol_15(buffer : SB, offset : u32) -> mat3x2<f32> {
return mat3x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u))); return mat3x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)));
} }
fn tint_symbol_16(buffer : [[access(read_write)]] SB, offset : u32) -> mat3x3<f32> { fn tint_symbol_16(buffer : SB, offset : u32) -> mat3x3<f32> {
return mat3x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u))); return mat3x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)));
} }
fn tint_symbol_17(buffer : [[access(read_write)]] SB, offset : u32) -> mat3x4<f32> { fn tint_symbol_17(buffer : SB, offset : u32) -> mat3x4<f32> {
return mat3x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u))); return mat3x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u)));
} }
fn tint_symbol_18(buffer : [[access(read_write)]] SB, offset : u32) -> mat4x2<f32> { fn tint_symbol_18(buffer : SB, offset : u32) -> mat4x2<f32> {
return mat4x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u))); return mat4x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u)));
} }
fn tint_symbol_19(buffer : [[access(read_write)]] SB, offset : u32) -> mat4x3<f32> { fn tint_symbol_19(buffer : SB, offset : u32) -> mat4x3<f32> {
return mat4x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 48u))); return mat4x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 48u)));
} }
fn tint_symbol_20(buffer : [[access(read_write)]] SB, offset : u32) -> mat4x4<f32> { fn tint_symbol_20(buffer : SB, offset : u32) -> mat4x4<f32> {
return mat4x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u)), tint_symbol_11(buffer, (offset + 48u))); return mat4x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u)), tint_symbol_11(buffer, (offset + 48u)));
} }
fn tint_symbol_21(buffer : [[access(read_write)]] SB, offset : u32) -> array<vec3<f32>, 2> { fn tint_symbol_21(buffer : SB, offset : u32) -> array<vec3<f32>, 2> {
return array<vec3<f32>, 2>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u))); return array<vec3<f32>, 2>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)));
} }
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -244,7 +244,7 @@ struct SB {
v : array<vec3<f32>, 2>; v : array<vec3<f32>, 2>;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -301,101 +301,101 @@ struct SB {
}; };
[[internal(intrinsic_store_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol(buffer : [[access(read_write)]] SB, offset : u32, value : i32) fn tint_symbol(buffer : SB, offset : u32, value : i32)
[[internal(intrinsic_store_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_1(buffer : [[access(read_write)]] SB, offset : u32, value : u32) fn tint_symbol_1(buffer : SB, offset : u32, value : u32)
[[internal(intrinsic_store_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_2(buffer : [[access(read_write)]] SB, offset : u32, value : f32) fn tint_symbol_2(buffer : SB, offset : u32, value : f32)
[[internal(intrinsic_store_vec2_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec2_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_3(buffer : [[access(read_write)]] SB, offset : u32, value : vec2<i32>) fn tint_symbol_3(buffer : SB, offset : u32, value : vec2<i32>)
[[internal(intrinsic_store_vec2_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec2_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_4(buffer : [[access(read_write)]] SB, offset : u32, value : vec2<u32>) fn tint_symbol_4(buffer : SB, offset : u32, value : vec2<u32>)
[[internal(intrinsic_store_vec2_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec2_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_5(buffer : [[access(read_write)]] SB, offset : u32, value : vec2<f32>) fn tint_symbol_5(buffer : SB, offset : u32, value : vec2<f32>)
[[internal(intrinsic_store_vec3_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec3_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_6(buffer : [[access(read_write)]] SB, offset : u32, value : vec3<i32>) fn tint_symbol_6(buffer : SB, offset : u32, value : vec3<i32>)
[[internal(intrinsic_store_vec3_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec3_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_7(buffer : [[access(read_write)]] SB, offset : u32, value : vec3<u32>) fn tint_symbol_7(buffer : SB, offset : u32, value : vec3<u32>)
[[internal(intrinsic_store_vec3_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec3_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_8(buffer : [[access(read_write)]] SB, offset : u32, value : vec3<f32>) fn tint_symbol_8(buffer : SB, offset : u32, value : vec3<f32>)
[[internal(intrinsic_store_vec4_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec4_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_9(buffer : [[access(read_write)]] SB, offset : u32, value : vec4<i32>) fn tint_symbol_9(buffer : SB, offset : u32, value : vec4<i32>)
[[internal(intrinsic_store_vec4_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec4_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_10(buffer : [[access(read_write)]] SB, offset : u32, value : vec4<u32>) fn tint_symbol_10(buffer : SB, offset : u32, value : vec4<u32>)
[[internal(intrinsic_store_vec4_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec4_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_11(buffer : [[access(read_write)]] SB, offset : u32, value : vec4<f32>) fn tint_symbol_11(buffer : SB, offset : u32, value : vec4<f32>)
fn tint_symbol_12(buffer : [[access(read_write)]] SB, offset : u32, value : mat2x2<f32>) { fn tint_symbol_12(buffer : SB, offset : u32, value : mat2x2<f32>) {
tint_symbol_5(buffer, (offset + 0u), value[0u]); tint_symbol_5(buffer, (offset + 0u), value[0u]);
tint_symbol_5(buffer, (offset + 8u), value[1u]); tint_symbol_5(buffer, (offset + 8u), value[1u]);
} }
fn tint_symbol_13(buffer : [[access(read_write)]] SB, offset : u32, value : mat2x3<f32>) { fn tint_symbol_13(buffer : SB, offset : u32, value : mat2x3<f32>) {
tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 0u), value[0u]);
tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 16u), value[1u]);
} }
fn tint_symbol_14(buffer : [[access(read_write)]] SB, offset : u32, value : mat2x4<f32>) { fn tint_symbol_14(buffer : SB, offset : u32, value : mat2x4<f32>) {
tint_symbol_11(buffer, (offset + 0u), value[0u]); tint_symbol_11(buffer, (offset + 0u), value[0u]);
tint_symbol_11(buffer, (offset + 16u), value[1u]); tint_symbol_11(buffer, (offset + 16u), value[1u]);
} }
fn tint_symbol_15(buffer : [[access(read_write)]] SB, offset : u32, value : mat3x2<f32>) { fn tint_symbol_15(buffer : SB, offset : u32, value : mat3x2<f32>) {
tint_symbol_5(buffer, (offset + 0u), value[0u]); tint_symbol_5(buffer, (offset + 0u), value[0u]);
tint_symbol_5(buffer, (offset + 8u), value[1u]); tint_symbol_5(buffer, (offset + 8u), value[1u]);
tint_symbol_5(buffer, (offset + 16u), value[2u]); tint_symbol_5(buffer, (offset + 16u), value[2u]);
} }
fn tint_symbol_16(buffer : [[access(read_write)]] SB, offset : u32, value : mat3x3<f32>) { fn tint_symbol_16(buffer : SB, offset : u32, value : mat3x3<f32>) {
tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 0u), value[0u]);
tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 16u), value[1u]);
tint_symbol_8(buffer, (offset + 32u), value[2u]); tint_symbol_8(buffer, (offset + 32u), value[2u]);
} }
fn tint_symbol_17(buffer : [[access(read_write)]] SB, offset : u32, value : mat3x4<f32>) { fn tint_symbol_17(buffer : SB, offset : u32, value : mat3x4<f32>) {
tint_symbol_11(buffer, (offset + 0u), value[0u]); tint_symbol_11(buffer, (offset + 0u), value[0u]);
tint_symbol_11(buffer, (offset + 16u), value[1u]); tint_symbol_11(buffer, (offset + 16u), value[1u]);
tint_symbol_11(buffer, (offset + 32u), value[2u]); tint_symbol_11(buffer, (offset + 32u), value[2u]);
} }
fn tint_symbol_18(buffer : [[access(read_write)]] SB, offset : u32, value : mat4x2<f32>) { fn tint_symbol_18(buffer : SB, offset : u32, value : mat4x2<f32>) {
tint_symbol_5(buffer, (offset + 0u), value[0u]); tint_symbol_5(buffer, (offset + 0u), value[0u]);
tint_symbol_5(buffer, (offset + 8u), value[1u]); tint_symbol_5(buffer, (offset + 8u), value[1u]);
tint_symbol_5(buffer, (offset + 16u), value[2u]); tint_symbol_5(buffer, (offset + 16u), value[2u]);
tint_symbol_5(buffer, (offset + 24u), value[3u]); tint_symbol_5(buffer, (offset + 24u), value[3u]);
} }
fn tint_symbol_19(buffer : [[access(read_write)]] SB, offset : u32, value : mat4x3<f32>) { fn tint_symbol_19(buffer : SB, offset : u32, value : mat4x3<f32>) {
tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 0u), value[0u]);
tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 16u), value[1u]);
tint_symbol_8(buffer, (offset + 32u), value[2u]); tint_symbol_8(buffer, (offset + 32u), value[2u]);
tint_symbol_8(buffer, (offset + 48u), value[3u]); tint_symbol_8(buffer, (offset + 48u), value[3u]);
} }
fn tint_symbol_20(buffer : [[access(read_write)]] SB, offset : u32, value : mat4x4<f32>) { fn tint_symbol_20(buffer : SB, offset : u32, value : mat4x4<f32>) {
tint_symbol_11(buffer, (offset + 0u), value[0u]); tint_symbol_11(buffer, (offset + 0u), value[0u]);
tint_symbol_11(buffer, (offset + 16u), value[1u]); tint_symbol_11(buffer, (offset + 16u), value[1u]);
tint_symbol_11(buffer, (offset + 32u), value[2u]); tint_symbol_11(buffer, (offset + 32u), value[2u]);
tint_symbol_11(buffer, (offset + 48u), value[3u]); tint_symbol_11(buffer, (offset + 48u), value[3u]);
} }
fn tint_symbol_21(buffer : [[access(read_write)]] SB, offset : u32, value : array<vec3<f32>, 2>) { fn tint_symbol_21(buffer : SB, offset : u32, value : array<vec3<f32>, 2>) {
tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 0u), value[0u]);
tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 16u), value[1u]);
} }
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -457,7 +457,7 @@ struct SB {
v : array<vec3<f32>, 2>; v : array<vec3<f32>, 2>;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -493,86 +493,86 @@ struct SB {
}; };
[[internal(intrinsic_load_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol(buffer : [[access(read_write)]] SB, offset : u32) -> i32 fn tint_symbol(buffer : SB, offset : u32) -> i32
[[internal(intrinsic_load_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_1(buffer : [[access(read_write)]] SB, offset : u32) -> u32 fn tint_symbol_1(buffer : SB, offset : u32) -> u32
[[internal(intrinsic_load_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_2(buffer : [[access(read_write)]] SB, offset : u32) -> f32 fn tint_symbol_2(buffer : SB, offset : u32) -> f32
[[internal(intrinsic_load_vec2_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec2_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_3(buffer : [[access(read_write)]] SB, offset : u32) -> vec2<i32> fn tint_symbol_3(buffer : SB, offset : u32) -> vec2<i32>
[[internal(intrinsic_load_vec2_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec2_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_4(buffer : [[access(read_write)]] SB, offset : u32) -> vec2<u32> fn tint_symbol_4(buffer : SB, offset : u32) -> vec2<u32>
[[internal(intrinsic_load_vec2_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec2_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_5(buffer : [[access(read_write)]] SB, offset : u32) -> vec2<f32> fn tint_symbol_5(buffer : SB, offset : u32) -> vec2<f32>
[[internal(intrinsic_load_vec3_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec3_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_6(buffer : [[access(read_write)]] SB, offset : u32) -> vec3<i32> fn tint_symbol_6(buffer : SB, offset : u32) -> vec3<i32>
[[internal(intrinsic_load_vec3_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec3_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_7(buffer : [[access(read_write)]] SB, offset : u32) -> vec3<u32> fn tint_symbol_7(buffer : SB, offset : u32) -> vec3<u32>
[[internal(intrinsic_load_vec3_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec3_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_8(buffer : [[access(read_write)]] SB, offset : u32) -> vec3<f32> fn tint_symbol_8(buffer : SB, offset : u32) -> vec3<f32>
[[internal(intrinsic_load_vec4_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec4_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_9(buffer : [[access(read_write)]] SB, offset : u32) -> vec4<i32> fn tint_symbol_9(buffer : SB, offset : u32) -> vec4<i32>
[[internal(intrinsic_load_vec4_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec4_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_10(buffer : [[access(read_write)]] SB, offset : u32) -> vec4<u32> fn tint_symbol_10(buffer : SB, offset : u32) -> vec4<u32>
[[internal(intrinsic_load_vec4_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_vec4_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_11(buffer : [[access(read_write)]] SB, offset : u32) -> vec4<f32> fn tint_symbol_11(buffer : SB, offset : u32) -> vec4<f32>
fn tint_symbol_12(buffer : [[access(read_write)]] SB, offset : u32) -> mat2x2<f32> { fn tint_symbol_12(buffer : SB, offset : u32) -> mat2x2<f32> {
return mat2x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u))); return mat2x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)));
} }
fn tint_symbol_13(buffer : [[access(read_write)]] SB, offset : u32) -> mat2x3<f32> { fn tint_symbol_13(buffer : SB, offset : u32) -> mat2x3<f32> {
return mat2x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u))); return mat2x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)));
} }
fn tint_symbol_14(buffer : [[access(read_write)]] SB, offset : u32) -> mat2x4<f32> { fn tint_symbol_14(buffer : SB, offset : u32) -> mat2x4<f32> {
return mat2x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u))); return mat2x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)));
} }
fn tint_symbol_15(buffer : [[access(read_write)]] SB, offset : u32) -> mat3x2<f32> { fn tint_symbol_15(buffer : SB, offset : u32) -> mat3x2<f32> {
return mat3x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u))); return mat3x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)));
} }
fn tint_symbol_16(buffer : [[access(read_write)]] SB, offset : u32) -> mat3x3<f32> { fn tint_symbol_16(buffer : SB, offset : u32) -> mat3x3<f32> {
return mat3x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u))); return mat3x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)));
} }
fn tint_symbol_17(buffer : [[access(read_write)]] SB, offset : u32) -> mat3x4<f32> { fn tint_symbol_17(buffer : SB, offset : u32) -> mat3x4<f32> {
return mat3x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u))); return mat3x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u)));
} }
fn tint_symbol_18(buffer : [[access(read_write)]] SB, offset : u32) -> mat4x2<f32> { fn tint_symbol_18(buffer : SB, offset : u32) -> mat4x2<f32> {
return mat4x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u))); return mat4x2<f32>(tint_symbol_5(buffer, (offset + 0u)), tint_symbol_5(buffer, (offset + 8u)), tint_symbol_5(buffer, (offset + 16u)), tint_symbol_5(buffer, (offset + 24u)));
} }
fn tint_symbol_19(buffer : [[access(read_write)]] SB, offset : u32) -> mat4x3<f32> { fn tint_symbol_19(buffer : SB, offset : u32) -> mat4x3<f32> {
return mat4x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 48u))); return mat4x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 48u)));
} }
fn tint_symbol_20(buffer : [[access(read_write)]] SB, offset : u32) -> mat4x4<f32> { fn tint_symbol_20(buffer : SB, offset : u32) -> mat4x4<f32> {
return mat4x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u)), tint_symbol_11(buffer, (offset + 48u))); return mat4x4<f32>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 32u)), tint_symbol_11(buffer, (offset + 48u)));
} }
fn tint_symbol_21(buffer : [[access(read_write)]] SB, offset : u32) -> array<vec3<f32>, 2> { fn tint_symbol_21(buffer : SB, offset : u32) -> array<vec3<f32>, 2> {
return array<vec3<f32>, 2>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u))); return array<vec3<f32>, 2>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)));
} }
fn tint_symbol_22(buffer : [[access(read_write)]] SB, offset : u32) -> SB { fn tint_symbol_22(buffer : SB, offset : u32) -> SB {
return SB(tint_symbol(buffer, (offset + 0u)), tint_symbol_1(buffer, (offset + 4u)), tint_symbol_2(buffer, (offset + 8u)), tint_symbol_3(buffer, (offset + 16u)), tint_symbol_4(buffer, (offset + 24u)), tint_symbol_5(buffer, (offset + 32u)), tint_symbol_6(buffer, (offset + 48u)), tint_symbol_7(buffer, (offset + 64u)), tint_symbol_8(buffer, (offset + 80u)), tint_symbol_9(buffer, (offset + 96u)), tint_symbol_10(buffer, (offset + 112u)), tint_symbol_11(buffer, (offset + 128u)), tint_symbol_12(buffer, (offset + 144u)), tint_symbol_13(buffer, (offset + 160u)), tint_symbol_14(buffer, (offset + 192u)), tint_symbol_15(buffer, (offset + 224u)), tint_symbol_16(buffer, (offset + 256u)), tint_symbol_17(buffer, (offset + 304u)), tint_symbol_18(buffer, (offset + 352u)), tint_symbol_19(buffer, (offset + 384u)), tint_symbol_20(buffer, (offset + 448u)), tint_symbol_21(buffer, (offset + 512u))); return SB(tint_symbol(buffer, (offset + 0u)), tint_symbol_1(buffer, (offset + 4u)), tint_symbol_2(buffer, (offset + 8u)), tint_symbol_3(buffer, (offset + 16u)), tint_symbol_4(buffer, (offset + 24u)), tint_symbol_5(buffer, (offset + 32u)), tint_symbol_6(buffer, (offset + 48u)), tint_symbol_7(buffer, (offset + 64u)), tint_symbol_8(buffer, (offset + 80u)), tint_symbol_9(buffer, (offset + 96u)), tint_symbol_10(buffer, (offset + 112u)), tint_symbol_11(buffer, (offset + 128u)), tint_symbol_12(buffer, (offset + 144u)), tint_symbol_13(buffer, (offset + 160u)), tint_symbol_14(buffer, (offset + 192u)), tint_symbol_15(buffer, (offset + 224u)), tint_symbol_16(buffer, (offset + 256u)), tint_symbol_17(buffer, (offset + 304u)), tint_symbol_18(buffer, (offset + 352u)), tint_symbol_19(buffer, (offset + 384u)), tint_symbol_20(buffer, (offset + 448u)), tint_symbol_21(buffer, (offset + 512u)));
} }
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -613,7 +613,7 @@ struct SB {
v : array<vec3<f32>, 2>; v : array<vec3<f32>, 2>;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -649,101 +649,101 @@ struct SB {
}; };
[[internal(intrinsic_store_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol(buffer : [[access(read_write)]] SB, offset : u32, value : i32) fn tint_symbol(buffer : SB, offset : u32, value : i32)
[[internal(intrinsic_store_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_1(buffer : [[access(read_write)]] SB, offset : u32, value : u32) fn tint_symbol_1(buffer : SB, offset : u32, value : u32)
[[internal(intrinsic_store_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_2(buffer : [[access(read_write)]] SB, offset : u32, value : f32) fn tint_symbol_2(buffer : SB, offset : u32, value : f32)
[[internal(intrinsic_store_vec2_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec2_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_3(buffer : [[access(read_write)]] SB, offset : u32, value : vec2<i32>) fn tint_symbol_3(buffer : SB, offset : u32, value : vec2<i32>)
[[internal(intrinsic_store_vec2_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec2_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_4(buffer : [[access(read_write)]] SB, offset : u32, value : vec2<u32>) fn tint_symbol_4(buffer : SB, offset : u32, value : vec2<u32>)
[[internal(intrinsic_store_vec2_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec2_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_5(buffer : [[access(read_write)]] SB, offset : u32, value : vec2<f32>) fn tint_symbol_5(buffer : SB, offset : u32, value : vec2<f32>)
[[internal(intrinsic_store_vec3_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec3_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_6(buffer : [[access(read_write)]] SB, offset : u32, value : vec3<i32>) fn tint_symbol_6(buffer : SB, offset : u32, value : vec3<i32>)
[[internal(intrinsic_store_vec3_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec3_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_7(buffer : [[access(read_write)]] SB, offset : u32, value : vec3<u32>) fn tint_symbol_7(buffer : SB, offset : u32, value : vec3<u32>)
[[internal(intrinsic_store_vec3_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec3_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_8(buffer : [[access(read_write)]] SB, offset : u32, value : vec3<f32>) fn tint_symbol_8(buffer : SB, offset : u32, value : vec3<f32>)
[[internal(intrinsic_store_vec4_u32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec4_u32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_9(buffer : [[access(read_write)]] SB, offset : u32, value : vec4<i32>) fn tint_symbol_9(buffer : SB, offset : u32, value : vec4<i32>)
[[internal(intrinsic_store_vec4_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec4_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_10(buffer : [[access(read_write)]] SB, offset : u32, value : vec4<u32>) fn tint_symbol_10(buffer : SB, offset : u32, value : vec4<u32>)
[[internal(intrinsic_store_vec4_i32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_store_vec4_i32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol_11(buffer : [[access(read_write)]] SB, offset : u32, value : vec4<f32>) fn tint_symbol_11(buffer : SB, offset : u32, value : vec4<f32>)
fn tint_symbol_12(buffer : [[access(read_write)]] SB, offset : u32, value : mat2x2<f32>) { fn tint_symbol_12(buffer : SB, offset : u32, value : mat2x2<f32>) {
tint_symbol_5(buffer, (offset + 0u), value[0u]); tint_symbol_5(buffer, (offset + 0u), value[0u]);
tint_symbol_5(buffer, (offset + 8u), value[1u]); tint_symbol_5(buffer, (offset + 8u), value[1u]);
} }
fn tint_symbol_13(buffer : [[access(read_write)]] SB, offset : u32, value : mat2x3<f32>) { fn tint_symbol_13(buffer : SB, offset : u32, value : mat2x3<f32>) {
tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 0u), value[0u]);
tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 16u), value[1u]);
} }
fn tint_symbol_14(buffer : [[access(read_write)]] SB, offset : u32, value : mat2x4<f32>) { fn tint_symbol_14(buffer : SB, offset : u32, value : mat2x4<f32>) {
tint_symbol_11(buffer, (offset + 0u), value[0u]); tint_symbol_11(buffer, (offset + 0u), value[0u]);
tint_symbol_11(buffer, (offset + 16u), value[1u]); tint_symbol_11(buffer, (offset + 16u), value[1u]);
} }
fn tint_symbol_15(buffer : [[access(read_write)]] SB, offset : u32, value : mat3x2<f32>) { fn tint_symbol_15(buffer : SB, offset : u32, value : mat3x2<f32>) {
tint_symbol_5(buffer, (offset + 0u), value[0u]); tint_symbol_5(buffer, (offset + 0u), value[0u]);
tint_symbol_5(buffer, (offset + 8u), value[1u]); tint_symbol_5(buffer, (offset + 8u), value[1u]);
tint_symbol_5(buffer, (offset + 16u), value[2u]); tint_symbol_5(buffer, (offset + 16u), value[2u]);
} }
fn tint_symbol_16(buffer : [[access(read_write)]] SB, offset : u32, value : mat3x3<f32>) { fn tint_symbol_16(buffer : SB, offset : u32, value : mat3x3<f32>) {
tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 0u), value[0u]);
tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 16u), value[1u]);
tint_symbol_8(buffer, (offset + 32u), value[2u]); tint_symbol_8(buffer, (offset + 32u), value[2u]);
} }
fn tint_symbol_17(buffer : [[access(read_write)]] SB, offset : u32, value : mat3x4<f32>) { fn tint_symbol_17(buffer : SB, offset : u32, value : mat3x4<f32>) {
tint_symbol_11(buffer, (offset + 0u), value[0u]); tint_symbol_11(buffer, (offset + 0u), value[0u]);
tint_symbol_11(buffer, (offset + 16u), value[1u]); tint_symbol_11(buffer, (offset + 16u), value[1u]);
tint_symbol_11(buffer, (offset + 32u), value[2u]); tint_symbol_11(buffer, (offset + 32u), value[2u]);
} }
fn tint_symbol_18(buffer : [[access(read_write)]] SB, offset : u32, value : mat4x2<f32>) { fn tint_symbol_18(buffer : SB, offset : u32, value : mat4x2<f32>) {
tint_symbol_5(buffer, (offset + 0u), value[0u]); tint_symbol_5(buffer, (offset + 0u), value[0u]);
tint_symbol_5(buffer, (offset + 8u), value[1u]); tint_symbol_5(buffer, (offset + 8u), value[1u]);
tint_symbol_5(buffer, (offset + 16u), value[2u]); tint_symbol_5(buffer, (offset + 16u), value[2u]);
tint_symbol_5(buffer, (offset + 24u), value[3u]); tint_symbol_5(buffer, (offset + 24u), value[3u]);
} }
fn tint_symbol_19(buffer : [[access(read_write)]] SB, offset : u32, value : mat4x3<f32>) { fn tint_symbol_19(buffer : SB, offset : u32, value : mat4x3<f32>) {
tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 0u), value[0u]);
tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 16u), value[1u]);
tint_symbol_8(buffer, (offset + 32u), value[2u]); tint_symbol_8(buffer, (offset + 32u), value[2u]);
tint_symbol_8(buffer, (offset + 48u), value[3u]); tint_symbol_8(buffer, (offset + 48u), value[3u]);
} }
fn tint_symbol_20(buffer : [[access(read_write)]] SB, offset : u32, value : mat4x4<f32>) { fn tint_symbol_20(buffer : SB, offset : u32, value : mat4x4<f32>) {
tint_symbol_11(buffer, (offset + 0u), value[0u]); tint_symbol_11(buffer, (offset + 0u), value[0u]);
tint_symbol_11(buffer, (offset + 16u), value[1u]); tint_symbol_11(buffer, (offset + 16u), value[1u]);
tint_symbol_11(buffer, (offset + 32u), value[2u]); tint_symbol_11(buffer, (offset + 32u), value[2u]);
tint_symbol_11(buffer, (offset + 48u), value[3u]); tint_symbol_11(buffer, (offset + 48u), value[3u]);
} }
fn tint_symbol_21(buffer : [[access(read_write)]] SB, offset : u32, value : array<vec3<f32>, 2>) { fn tint_symbol_21(buffer : SB, offset : u32, value : array<vec3<f32>, 2>) {
tint_symbol_8(buffer, (offset + 0u), value[0u]); tint_symbol_8(buffer, (offset + 0u), value[0u]);
tint_symbol_8(buffer, (offset + 16u), value[1u]); tint_symbol_8(buffer, (offset + 16u), value[1u]);
} }
fn tint_symbol_22(buffer : [[access(read_write)]] SB, offset : u32, value : SB) { fn tint_symbol_22(buffer : SB, offset : u32, value : SB) {
tint_symbol(buffer, (offset + 0u), value.a); tint_symbol(buffer, (offset + 0u), value.a);
tint_symbol_1(buffer, (offset + 4u), value.b); tint_symbol_1(buffer, (offset + 4u), value.b);
tint_symbol_2(buffer, (offset + 8u), value.c); tint_symbol_2(buffer, (offset + 8u), value.c);
@ -768,7 +768,7 @@ fn tint_symbol_22(buffer : [[access(read_write)]] SB, offset : u32, value : SB)
tint_symbol_21(buffer, (offset + 512u), value.v); tint_symbol_21(buffer, (offset + 512u), value.v);
} }
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -802,7 +802,7 @@ struct SB {
b : [[stride(256)]] array<S2>; b : [[stride(256)]] array<S2>;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -838,9 +838,9 @@ struct SB {
}; };
[[internal(intrinsic_load_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol(buffer : [[access(read_write)]] SB, offset : u32) -> f32 fn tint_symbol(buffer : SB, offset : u32) -> f32
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -874,7 +874,7 @@ struct SB {
b : [[stride(256)]] array<S2>; b : [[stride(256)]] array<S2>;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -906,9 +906,9 @@ struct SB {
}; };
[[internal(intrinsic_load_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol(buffer : [[access(read_write)]] SB, offset : u32) -> f32 fn tint_symbol(buffer : SB, offset : u32) -> f32
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -953,7 +953,7 @@ struct SB {
b : A2_Array; b : A2_Array;
}; };
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {
@ -993,9 +993,9 @@ struct SB {
}; };
[[internal(intrinsic_load_f32), internal(disable_validation__function_has_no_body)]] [[internal(intrinsic_load_f32), internal(disable_validation__function_has_no_body)]]
fn tint_symbol(buffer : [[access(read_write)]] SB, offset : u32) -> f32 fn tint_symbol(buffer : SB, offset : u32) -> f32
[[group(0), binding(0)]] var<storage> sb : [[access(read_write)]] SB; [[group(0), binding(0)]] var<storage, read_write> sb : SB;
[[stage(compute)]] [[stage(compute)]]
fn main() { fn main() {

View File

@ -115,8 +115,9 @@ Output ExternalTextureTransform::Run(const Program* in, const DataMap&) {
auto* clonedConstructor = ctx.Clone(var->constructor()); auto* clonedConstructor = ctx.Clone(var->constructor());
auto clonedDecorations = ctx.Clone(var->decorations()); auto clonedDecorations = ctx.Clone(var->decorations());
auto* newVar = ctx.dst->create<ast::Variable>( auto* newVar = ctx.dst->create<ast::Variable>(
clonedSrc, clonedSym, var->declared_storage_class(), newType, clonedSrc, clonedSym, var->declared_storage_class(),
var->is_const(), clonedConstructor, clonedDecorations); var->declared_access(), newType, var->is_const(), clonedConstructor,
clonedDecorations);
ctx.Replace(var, newVar); ctx.Replace(var, newVar);
} }

View File

@ -214,10 +214,10 @@ struct State {
ctx.dst->create<ast::StructBlockDecoration>(), ctx.dst->create<ast::StructBlockDecoration>(),
}); });
for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) { for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
auto* access = ctx.dst->ty.access(ast::AccessControl::kRead, struct_type);
// The decorated variable with struct type // The decorated variable with struct type
ctx.dst->Global( ctx.dst->Global(
GetVertexBufferName(i), access, ast::StorageClass::kStorage, nullptr, GetVertexBufferName(i), struct_type, ast::StorageClass::kStorage,
ast::Access::kRead,
ast::DecorationList{ ast::DecorationList{
ctx.dst->create<ast::BindingDecoration>(i), ctx.dst->create<ast::BindingDecoration>(i),
ctx.dst->create<ast::GroupDecoration>(cfg.pulling_group), ctx.dst->create<ast::GroupDecoration>(cfg.pulling_group),

View File

@ -121,7 +121,7 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
[[stage(vertex)]] [[stage(vertex)]]
fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> { fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
@ -161,7 +161,7 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
[[stage(vertex)]] [[stage(vertex)]]
fn main([[builtin(instance_index)]] tint_pulling_instance_index : u32) -> [[builtin(position)]] vec4<f32> { fn main([[builtin(instance_index)]] tint_pulling_instance_index : u32) -> [[builtin(position)]] vec4<f32> {
@ -201,7 +201,7 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(5)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(5)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
[[stage(vertex)]] [[stage(vertex)]]
fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> { fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
@ -246,7 +246,7 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
struct Inputs { struct Inputs {
[[location(0)]] [[location(0)]]
@ -296,9 +296,9 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
[[binding(1), group(4)]] var<storage> tint_pulling_vertex_buffer_1 : [[access(read)]] TintVertexData; [[binding(1), group(4)]] var<storage, read> tint_pulling_vertex_buffer_1 : TintVertexData;
[[stage(vertex)]] [[stage(vertex)]]
fn main([[builtin(vertex_index)]] custom_vertex_index : u32, [[builtin(instance_index)]] custom_instance_index : u32) -> [[builtin(position)]] vec4<f32> { fn main([[builtin(vertex_index)]] custom_vertex_index : u32, [[builtin(instance_index)]] custom_instance_index : u32) -> [[builtin(position)]] vec4<f32> {
@ -358,9 +358,9 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
[[binding(1), group(4)]] var<storage> tint_pulling_vertex_buffer_1 : [[access(read)]] TintVertexData; [[binding(1), group(4)]] var<storage, read> tint_pulling_vertex_buffer_1 : TintVertexData;
struct tint_symbol { struct tint_symbol {
[[builtin(vertex_index)]] [[builtin(vertex_index)]]
@ -442,9 +442,9 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
[[binding(1), group(4)]] var<storage> tint_pulling_vertex_buffer_1 : [[access(read)]] TintVertexData; [[binding(1), group(4)]] var<storage, read> tint_pulling_vertex_buffer_1 : TintVertexData;
struct Inputs { struct Inputs {
[[location(0)]] [[location(0)]]
@ -511,7 +511,7 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
[[stage(vertex)]] [[stage(vertex)]]
fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> { fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
@ -559,11 +559,11 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
[[binding(1), group(4)]] var<storage> tint_pulling_vertex_buffer_1 : [[access(read)]] TintVertexData; [[binding(1), group(4)]] var<storage, read> tint_pulling_vertex_buffer_1 : TintVertexData;
[[binding(2), group(4)]] var<storage> tint_pulling_vertex_buffer_2 : [[access(read)]] TintVertexData; [[binding(2), group(4)]] var<storage, read> tint_pulling_vertex_buffer_2 : TintVertexData;
[[stage(vertex)]] [[stage(vertex)]]
fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> { fn main([[builtin(vertex_index)]] tint_pulling_vertex_index : u32) -> [[builtin(position)]] vec4<f32> {
@ -617,7 +617,7 @@ struct TintVertexData {
tint_vertex_data_1 : [[stride(4)]] array<u32>; tint_vertex_data_1 : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0_1 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0_1 : TintVertexData;
[[stage(vertex)]] [[stage(vertex)]]
fn main([[builtin(vertex_index)]] tint_pulling_vertex_index_1 : u32) -> [[builtin(position)]] vec4<f32> { fn main([[builtin(vertex_index)]] tint_pulling_vertex_index_1 : u32) -> [[builtin(position)]] vec4<f32> {
@ -671,7 +671,7 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(5)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(5)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
var<private> var_a : f32; var<private> var_a : f32;
@ -720,9 +720,9 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
[[binding(1), group(4)]] var<storage> tint_pulling_vertex_buffer_1 : [[access(read)]] TintVertexData; [[binding(1), group(4)]] var<storage, read> tint_pulling_vertex_buffer_1 : TintVertexData;
var<private> var_a : f32; var<private> var_a : f32;
@ -787,7 +787,7 @@ struct TintVertexData {
tint_vertex_data : [[stride(4)]] array<u32>; tint_vertex_data : [[stride(4)]] array<u32>;
}; };
[[binding(0), group(4)]] var<storage> tint_pulling_vertex_buffer_0 : [[access(read)]] TintVertexData; [[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
var<private> var_a : f32; var<private> var_a : f32;

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