[wgsl-reader][wgsl-writer] Update variable decorations to new syntax.
This CL updates the variable decorations to require ()'s around parameters. Bug: tint:238 Change-Id: I835879f41349756ace553a52fc2d460173e70dce Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/28583 Commit-Queue: dan sinclair <dsinclair@chromium.org> Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com>
This commit is contained in:
parent
077d16d5e1
commit
35552f2a48
|
@ -492,26 +492,44 @@ ast::VariableDecorationList ParserImpl::variable_decoration_list() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// variable_decoration
|
// variable_decoration
|
||||||
// : LOCATION INT_LITERAL
|
// : LOCATION PAREN_LEFT INT_LITERAL PAREN_RIGHT
|
||||||
// | BUILTIN IDENT
|
// | BUILTIN PAREN_LEFT IDENT PAREN_RIGHT
|
||||||
// | BINDING INT_LITERAL
|
// | BINDING PAREN_LEFT INT_LITERAL PAREN_RIGHT
|
||||||
// | SET INT_LITERAL
|
// | SET INT PAREN_LEFT_LITERAL PAREN_RIGHT
|
||||||
std::unique_ptr<ast::VariableDecoration> ParserImpl::variable_decoration() {
|
std::unique_ptr<ast::VariableDecoration> ParserImpl::variable_decoration() {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (t.IsLocation()) {
|
if (t.IsLocation()) {
|
||||||
next(); // consume the peek
|
next(); // consume the peek
|
||||||
|
|
||||||
|
t = next();
|
||||||
|
if (!t.IsParenLeft()) {
|
||||||
|
set_error(t, "missing ( for location decoration");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
t = next();
|
t = next();
|
||||||
if (!t.IsSintLiteral()) {
|
if (!t.IsSintLiteral()) {
|
||||||
set_error(t, "invalid value for location decoration");
|
set_error(t, "invalid value for location decoration");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
int32_t val = t.to_i32();
|
||||||
|
|
||||||
return std::make_unique<ast::LocationDecoration>(t.to_i32());
|
t = next();
|
||||||
|
if (!t.IsParenRight()) {
|
||||||
|
set_error(t, "missing ) for location decoration");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return std::make_unique<ast::LocationDecoration>(val);
|
||||||
}
|
}
|
||||||
if (t.IsBuiltin()) {
|
if (t.IsBuiltin()) {
|
||||||
next(); // consume the peek
|
next(); // consume the peek
|
||||||
|
|
||||||
|
t = next();
|
||||||
|
if (!t.IsParenLeft()) {
|
||||||
|
set_error(t, "missing ( for builtin decoration");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
t = next();
|
t = next();
|
||||||
if (!t.IsIdentifier() || t.to_str().empty()) {
|
if (!t.IsIdentifier() || t.to_str().empty()) {
|
||||||
set_error(t, "expected identifier for builtin");
|
set_error(t, "expected identifier for builtin");
|
||||||
|
@ -524,29 +542,60 @@ std::unique_ptr<ast::VariableDecoration> ParserImpl::variable_decoration() {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t = next();
|
||||||
|
if (!t.IsParenRight()) {
|
||||||
|
set_error(t, "missing ) for builtin decoration");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
return std::make_unique<ast::BuiltinDecoration>(builtin);
|
return std::make_unique<ast::BuiltinDecoration>(builtin);
|
||||||
}
|
}
|
||||||
if (t.IsBinding()) {
|
if (t.IsBinding()) {
|
||||||
next(); // consume the peek
|
next(); // consume the peek
|
||||||
|
|
||||||
|
t = next();
|
||||||
|
if (!t.IsParenLeft()) {
|
||||||
|
set_error(t, "missing ( for binding decoration");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
t = next();
|
t = next();
|
||||||
if (!t.IsSintLiteral()) {
|
if (!t.IsSintLiteral()) {
|
||||||
set_error(t, "invalid value for binding decoration");
|
set_error(t, "invalid value for binding decoration");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
int32_t val = t.to_i32();
|
||||||
|
|
||||||
return std::make_unique<ast::BindingDecoration>(t.to_i32());
|
t = next();
|
||||||
|
if (!t.IsParenRight()) {
|
||||||
|
set_error(t, "missing ) for binding decoration");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique<ast::BindingDecoration>(val);
|
||||||
}
|
}
|
||||||
if (t.IsSet()) {
|
if (t.IsSet()) {
|
||||||
next(); // consume the peek
|
next(); // consume the peek
|
||||||
|
|
||||||
|
t = next();
|
||||||
|
if (!t.IsParenLeft()) {
|
||||||
|
set_error(t, "missing ( for set decoration");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
t = next();
|
t = next();
|
||||||
if (!t.IsSintLiteral()) {
|
if (!t.IsSintLiteral()) {
|
||||||
set_error(t, "invalid value for set decoration");
|
set_error(t, "invalid value for set decoration");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
uint32_t val = t.to_i32();
|
||||||
|
|
||||||
return std::make_unique<ast::SetDecoration>(t.to_i32());
|
t = next();
|
||||||
|
if (!t.IsParenRight()) {
|
||||||
|
set_error(t, "missing ) for set decoration");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique<ast::SetDecoration>(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -55,7 +55,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
|
||||||
auto* p = parser("[[binding 2, set 1]] var<out> a : f32");
|
auto* p = parser("[[binding(2), set(1)]] var<out> a : f32");
|
||||||
auto e = p->global_variable_decl();
|
auto e = p->global_variable_decl();
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_NE(e, nullptr);
|
ASSERT_NE(e, nullptr);
|
||||||
|
@ -78,11 +78,11 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidDecoration) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidDecoration) {
|
||||||
auto* p = parser("[[binding]] var<out> a : f32");
|
auto* p = parser("[[binding()]] var<out> a : f32");
|
||||||
auto e = p->global_variable_decl();
|
auto e = p->global_variable_decl();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(e, nullptr);
|
ASSERT_EQ(e, nullptr);
|
||||||
EXPECT_EQ(p->error(), "1:10: invalid value for binding decoration");
|
EXPECT_EQ(p->error(), "1:11: invalid value for binding decoration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
|
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
|
||||||
|
|
|
@ -32,7 +32,7 @@ TEST_F(ParserImplTest, Parses) {
|
||||||
auto* p = parser(R"(
|
auto* p = parser(R"(
|
||||||
import "GLSL.std.430" as glsl;
|
import "GLSL.std.430" as glsl;
|
||||||
|
|
||||||
[[location 0]] var<out> gl_FragColor : vec4<f32>;
|
[[location(0)]] var<out> gl_FragColor : vec4<f32>;
|
||||||
|
|
||||||
entry_point vertex = main;
|
entry_point vertex = main;
|
||||||
fn main() -> void {
|
fn main() -> void {
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace wgsl {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecorationList_Parses) {
|
TEST_F(ParserImplTest, VariableDecorationList_Parses) {
|
||||||
auto* p = parser(R"([[location 4, builtin position]])");
|
auto* p = parser(R"([[location(4), builtin(position)]])");
|
||||||
auto decos = p->variable_decoration_list();
|
auto decos = p->variable_decoration_list();
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
ASSERT_EQ(decos.size(), 2u);
|
ASSERT_EQ(decos.size(), 2u);
|
||||||
|
@ -49,28 +49,28 @@ TEST_F(ParserImplTest, VariableDecorationList_Invalid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecorationList_ExtraComma) {
|
TEST_F(ParserImplTest, VariableDecorationList_ExtraComma) {
|
||||||
auto* p = parser(R"([[builtin position, ]])");
|
auto* p = parser(R"([[builtin(position), ]])");
|
||||||
auto decos = p->variable_decoration_list();
|
auto decos = p->variable_decoration_list();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:21: missing variable decoration after comma");
|
ASSERT_EQ(p->error(), "1:22: missing variable decoration after comma");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecorationList_MissingComma) {
|
TEST_F(ParserImplTest, VariableDecorationList_MissingComma) {
|
||||||
auto* p = parser(R"([[binding 4 location 5]])");
|
auto* p = parser(R"([[binding(4) location(5)]])");
|
||||||
auto decos = p->variable_decoration_list();
|
auto decos = p->variable_decoration_list();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:13: missing comma in variable decoration list");
|
ASSERT_EQ(p->error(), "1:14: missing comma in variable decoration list");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecorationList_BadDecoration) {
|
TEST_F(ParserImplTest, VariableDecorationList_BadDecoration) {
|
||||||
auto* p = parser(R"([[location bad]])");
|
auto* p = parser(R"([[location(bad)]])");
|
||||||
auto decos = p->variable_decoration_list();
|
auto decos = p->variable_decoration_list();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:12: invalid value for location decoration");
|
ASSERT_EQ(p->error(), "1:12: invalid value for location decoration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecorationList_InvalidBuiltin) {
|
TEST_F(ParserImplTest, VariableDecorationList_InvalidBuiltin) {
|
||||||
auto* p = parser("[[builtin invalid]]");
|
auto* p = parser("[[builtin(invalid)]]");
|
||||||
auto decos = p->variable_decoration_list();
|
auto decos = p->variable_decoration_list();
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
ASSERT_EQ(p->error(), "1:11: invalid value for builtin decoration");
|
ASSERT_EQ(p->error(), "1:11: invalid value for builtin decoration");
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace wgsl {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Location) {
|
TEST_F(ParserImplTest, VariableDecoration_Location) {
|
||||||
auto* p = parser("location 4");
|
auto* p = parser("location(4)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_NE(deco, nullptr);
|
ASSERT_NE(deco, nullptr);
|
||||||
ASSERT_FALSE(p->has_error());
|
ASSERT_FALSE(p->has_error());
|
||||||
|
@ -36,16 +36,32 @@ TEST_F(ParserImplTest, VariableDecoration_Location) {
|
||||||
EXPECT_EQ(loc->value(), 4u);
|
EXPECT_EQ(loc->value(), 4u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Location_MissingValue) {
|
TEST_F(ParserImplTest, VariableDecoration_Location_MissingLeftParen) {
|
||||||
auto* p = parser("location");
|
auto* p = parser("location 4)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_EQ(deco, nullptr);
|
ASSERT_EQ(deco, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), "1:9: invalid value for location decoration");
|
EXPECT_EQ(p->error(), "1:10: missing ( for location decoration");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, VariableDecoration_Location_MissingRightParen) {
|
||||||
|
auto* p = parser("location(4");
|
||||||
|
auto deco = p->variable_decoration();
|
||||||
|
ASSERT_EQ(deco, nullptr);
|
||||||
|
ASSERT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:11: missing ) for location decoration");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, VariableDecoration_Location_MissingValue) {
|
||||||
|
auto* p = parser("location()");
|
||||||
|
auto deco = p->variable_decoration();
|
||||||
|
ASSERT_EQ(deco, nullptr);
|
||||||
|
ASSERT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:10: invalid value for location decoration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Location_MissingInvalid) {
|
TEST_F(ParserImplTest, VariableDecoration_Location_MissingInvalid) {
|
||||||
auto* p = parser("location nan");
|
auto* p = parser("location(nan)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_EQ(deco, nullptr);
|
ASSERT_EQ(deco, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
|
@ -81,7 +97,7 @@ class BuiltinTest : public testing::TestWithParam<BuiltinData> {
|
||||||
|
|
||||||
TEST_P(BuiltinTest, VariableDecoration_Builtin) {
|
TEST_P(BuiltinTest, VariableDecoration_Builtin) {
|
||||||
auto params = GetParam();
|
auto params = GetParam();
|
||||||
auto* p = parser(std::string("builtin ") + params.input);
|
auto* p = parser(std::string("builtin(") + params.input + ")");
|
||||||
|
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_FALSE(p->has_error()) << p->error();
|
ASSERT_FALSE(p->has_error()) << p->error();
|
||||||
|
@ -107,16 +123,32 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
BuiltinData{"global_invocation_id",
|
BuiltinData{"global_invocation_id",
|
||||||
ast::Builtin::kGlobalInvocationId}));
|
ast::Builtin::kGlobalInvocationId}));
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingValue) {
|
TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingLeftParen) {
|
||||||
auto* p = parser("builtin");
|
auto* p = parser("builtin position)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_EQ(deco, nullptr);
|
ASSERT_EQ(deco, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), "1:8: expected identifier for builtin");
|
EXPECT_EQ(p->error(), "1:9: missing ( for builtin decoration");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingRightParen) {
|
||||||
|
auto* p = parser("builtin(position");
|
||||||
|
auto deco = p->variable_decoration();
|
||||||
|
ASSERT_EQ(deco, nullptr);
|
||||||
|
ASSERT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:17: missing ) for builtin decoration");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingValue) {
|
||||||
|
auto* p = parser("builtin()");
|
||||||
|
auto deco = p->variable_decoration();
|
||||||
|
ASSERT_EQ(deco, nullptr);
|
||||||
|
ASSERT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:9: expected identifier for builtin");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Builtin_InvalidValue) {
|
TEST_F(ParserImplTest, VariableDecoration_Builtin_InvalidValue) {
|
||||||
auto* p = parser("builtin other_thingy");
|
auto* p = parser("builtin(other_thingy)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_EQ(deco, nullptr);
|
ASSERT_EQ(deco, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
|
@ -124,7 +156,7 @@ TEST_F(ParserImplTest, VariableDecoration_Builtin_InvalidValue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingInvalid) {
|
TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingInvalid) {
|
||||||
auto* p = parser("builtin 3");
|
auto* p = parser("builtin(3)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_EQ(deco, nullptr);
|
ASSERT_EQ(deco, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
|
@ -132,7 +164,7 @@ TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingInvalid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Binding) {
|
TEST_F(ParserImplTest, VariableDecoration_Binding) {
|
||||||
auto* p = parser("binding 4");
|
auto* p = parser("binding(4)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_NE(deco, nullptr);
|
ASSERT_NE(deco, nullptr);
|
||||||
ASSERT_FALSE(p->has_error());
|
ASSERT_FALSE(p->has_error());
|
||||||
|
@ -142,16 +174,32 @@ TEST_F(ParserImplTest, VariableDecoration_Binding) {
|
||||||
EXPECT_EQ(binding->value(), 4u);
|
EXPECT_EQ(binding->value(), 4u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Binding_MissingValue) {
|
TEST_F(ParserImplTest, VariableDecoration_Binding_MissingLeftParen) {
|
||||||
auto* p = parser("binding");
|
auto* p = parser("binding 4)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_EQ(deco, nullptr);
|
ASSERT_EQ(deco, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), "1:8: invalid value for binding decoration");
|
EXPECT_EQ(p->error(), "1:9: missing ( for binding decoration");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, VariableDecoration_Binding_MissingRightParen) {
|
||||||
|
auto* p = parser("binding(4");
|
||||||
|
auto deco = p->variable_decoration();
|
||||||
|
ASSERT_EQ(deco, nullptr);
|
||||||
|
ASSERT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:10: missing ) for binding decoration");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, VariableDecoration_Binding_MissingValue) {
|
||||||
|
auto* p = parser("binding()");
|
||||||
|
auto deco = p->variable_decoration();
|
||||||
|
ASSERT_EQ(deco, nullptr);
|
||||||
|
ASSERT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:9: invalid value for binding decoration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Binding_MissingInvalid) {
|
TEST_F(ParserImplTest, VariableDecoration_Binding_MissingInvalid) {
|
||||||
auto* p = parser("binding nan");
|
auto* p = parser("binding(nan)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_EQ(deco, nullptr);
|
ASSERT_EQ(deco, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
|
@ -159,7 +207,7 @@ TEST_F(ParserImplTest, VariableDecoration_Binding_MissingInvalid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_set) {
|
TEST_F(ParserImplTest, VariableDecoration_set) {
|
||||||
auto* p = parser("set 4");
|
auto* p = parser("set(4)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_FALSE(p->has_error());
|
ASSERT_FALSE(p->has_error());
|
||||||
ASSERT_NE(deco.get(), nullptr);
|
ASSERT_NE(deco.get(), nullptr);
|
||||||
|
@ -169,16 +217,32 @@ TEST_F(ParserImplTest, VariableDecoration_set) {
|
||||||
EXPECT_EQ(set->value(), 4u);
|
EXPECT_EQ(set->value(), 4u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Set_MissingValue) {
|
TEST_F(ParserImplTest, VariableDecoration_Set_MissingLeftParen) {
|
||||||
auto* p = parser("set");
|
auto* p = parser("set 2)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_EQ(deco, nullptr);
|
ASSERT_EQ(deco, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), "1:4: invalid value for set decoration");
|
EXPECT_EQ(p->error(), "1:5: missing ( for set decoration");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, VariableDecoration_Set_MissingRightParen) {
|
||||||
|
auto* p = parser("set(2");
|
||||||
|
auto deco = p->variable_decoration();
|
||||||
|
ASSERT_EQ(deco, nullptr);
|
||||||
|
ASSERT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:6: missing ) for set decoration");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserImplTest, VariableDecoration_Set_MissingValue) {
|
||||||
|
auto* p = parser("set()");
|
||||||
|
auto deco = p->variable_decoration();
|
||||||
|
ASSERT_EQ(deco, nullptr);
|
||||||
|
ASSERT_TRUE(p->has_error());
|
||||||
|
EXPECT_EQ(p->error(), "1:5: invalid value for set decoration");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, VariableDecoration_Set_MissingInvalid) {
|
TEST_F(ParserImplTest, VariableDecoration_Set_MissingInvalid) {
|
||||||
auto* p = parser("set nan");
|
auto* p = parser("set(nan)");
|
||||||
auto deco = p->variable_decoration();
|
auto deco = p->variable_decoration();
|
||||||
ASSERT_EQ(deco, nullptr);
|
ASSERT_EQ(deco, nullptr);
|
||||||
ASSERT_TRUE(p->has_error());
|
ASSERT_TRUE(p->has_error());
|
||||||
|
|
|
@ -36,7 +36,7 @@ TEST_F(ParserTest, Parses) {
|
||||||
Parser p(&ctx, R"(
|
Parser p(&ctx, R"(
|
||||||
import "GLSL.std.430" as glsl;
|
import "GLSL.std.430" as glsl;
|
||||||
|
|
||||||
[[location 0]] var<out> gl_FragColor : vec4<f32>;
|
[[location(0)]] var<out> gl_FragColor : vec4<f32>;
|
||||||
|
|
||||||
entry_point vertex = main;
|
entry_point vertex = main;
|
||||||
fn main() -> void {
|
fn main() -> void {
|
||||||
|
|
|
@ -37,8 +37,8 @@ namespace {
|
||||||
using HlslGeneratorImplTest_EntryPoint = TestHelper;
|
using HlslGeneratorImplTest_EntryPoint = TestHelper;
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Vertex_Input) {
|
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Vertex_Input) {
|
||||||
// [[location 0]] var<in> foo : f32;
|
// [[location(0)]] var<in> foo : f32;
|
||||||
// [[location 1]] var<in> bar : i32;
|
// [[location(1)]] var<in> bar : i32;
|
||||||
//
|
//
|
||||||
// struct vtx_main_in {
|
// struct vtx_main_in {
|
||||||
// float foo : TEXCOORD0;
|
// float foo : TEXCOORD0;
|
||||||
|
@ -98,8 +98,8 @@ TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Vertex_Input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Vertex_Output) {
|
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Vertex_Output) {
|
||||||
// [[location 0]] var<out> foo : f32;
|
// [[location(0)]] var<out> foo : f32;
|
||||||
// [[location 1]] var<out> bar : i32;
|
// [[location(1)]] var<out> bar : i32;
|
||||||
//
|
//
|
||||||
// struct vtx_main_out {
|
// struct vtx_main_out {
|
||||||
// float foo : TEXCOORD0;
|
// float foo : TEXCOORD0;
|
||||||
|
@ -159,8 +159,8 @@ TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Vertex_Output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Fragment_Input) {
|
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Fragment_Input) {
|
||||||
// [[location 0]] var<in> foo : f32;
|
// [[location(0)]] var<in> foo : f32;
|
||||||
// [[location 1]] var<in> bar : i32;
|
// [[location(1)]] var<in> bar : i32;
|
||||||
//
|
//
|
||||||
// struct frag_main_in {
|
// struct frag_main_in {
|
||||||
// float foo : TEXCOORD0;
|
// float foo : TEXCOORD0;
|
||||||
|
@ -220,8 +220,8 @@ TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Fragment_Input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Fragment_Output) {
|
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Fragment_Output) {
|
||||||
// [[location 0]] var<out> foo : f32;
|
// [[location(0)]] var<out> foo : f32;
|
||||||
// [[location 1]] var<out> bar : i32;
|
// [[location(1)]] var<out> bar : i32;
|
||||||
//
|
//
|
||||||
// struct frag_main_out {
|
// struct frag_main_out {
|
||||||
// float foo : SV_Target0;
|
// float foo : SV_Target0;
|
||||||
|
@ -281,8 +281,8 @@ TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Fragment_Output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Compute_Input) {
|
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Compute_Input) {
|
||||||
// [[location 0]] var<in> foo : f32;
|
// [[location(0)]] var<in> foo : f32;
|
||||||
// [[location 1]] var<in> bar : i32;
|
// [[location(1)]] var<in> bar : i32;
|
||||||
//
|
//
|
||||||
// -> Error, not allowed
|
// -> Error, not allowed
|
||||||
|
|
||||||
|
@ -334,8 +334,8 @@ TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Compute_Input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Compute_Output) {
|
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Compute_Output) {
|
||||||
// [[location 0]] var<out> foo : f32;
|
// [[location(0)]] var<out> foo : f32;
|
||||||
// [[location 1]] var<out> bar : i32;
|
// [[location(1)]] var<out> bar : i32;
|
||||||
//
|
//
|
||||||
// -> Error not allowed
|
// -> Error not allowed
|
||||||
|
|
||||||
|
@ -387,8 +387,8 @@ TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Compute_Output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Builtins) {
|
TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Builtins) {
|
||||||
// [[builtin frag_coord]] var<in> coord : vec4<f32>;
|
// [[builtin(frag_coord)]] var<in> coord : vec4<f32>;
|
||||||
// [[builtin frag_depth]] var<out> depth : f32;
|
// [[builtin(frag_depth)]] var<out> depth : f32;
|
||||||
//
|
//
|
||||||
// struct main_in {
|
// struct main_in {
|
||||||
// vector<float, 4> coord : SV_Position;
|
// vector<float, 4> coord : SV_Position;
|
||||||
|
|
|
@ -37,8 +37,8 @@ namespace {
|
||||||
using MslGeneratorImplTest = testing::Test;
|
using MslGeneratorImplTest = testing::Test;
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Vertex_Input) {
|
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Vertex_Input) {
|
||||||
// [[location 0]] var<in> foo : f32;
|
// [[location(0)]] var<in> foo : f32;
|
||||||
// [[location 1]] var<in> bar : i32;
|
// [[location(1)]] var<in> bar : i32;
|
||||||
//
|
//
|
||||||
// struct vtx_main_in {
|
// struct vtx_main_in {
|
||||||
// float foo [[attribute(0)]];
|
// float foo [[attribute(0)]];
|
||||||
|
@ -103,8 +103,8 @@ TEST_F(MslGeneratorImplTest, EmitEntryPointData_Vertex_Input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Vertex_Output) {
|
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Vertex_Output) {
|
||||||
// [[location 0]] var<out> foo : f32;
|
// [[location(0)]] var<out> foo : f32;
|
||||||
// [[location 1]] var<out> bar : i32;
|
// [[location(1)]] var<out> bar : i32;
|
||||||
//
|
//
|
||||||
// struct vtx_main_out {
|
// struct vtx_main_out {
|
||||||
// float foo [[user(locn0)]];
|
// float foo [[user(locn0)]];
|
||||||
|
@ -169,8 +169,8 @@ TEST_F(MslGeneratorImplTest, EmitEntryPointData_Vertex_Output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Fragment_Input) {
|
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Fragment_Input) {
|
||||||
// [[location 0]] var<in> foo : f32;
|
// [[location(0)]] var<in> foo : f32;
|
||||||
// [[location 1]] var<in> bar : i32;
|
// [[location(1)]] var<in> bar : i32;
|
||||||
//
|
//
|
||||||
// struct frag_main_in {
|
// struct frag_main_in {
|
||||||
// float foo [[user(locn0)]];
|
// float foo [[user(locn0)]];
|
||||||
|
@ -235,8 +235,8 @@ TEST_F(MslGeneratorImplTest, EmitEntryPointData_Fragment_Input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Fragment_Output) {
|
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Fragment_Output) {
|
||||||
// [[location 0]] var<out> foo : f32;
|
// [[location(0)]] var<out> foo : f32;
|
||||||
// [[location 1]] var<out> bar : i32;
|
// [[location(1)]] var<out> bar : i32;
|
||||||
//
|
//
|
||||||
// struct frag_main_out {
|
// struct frag_main_out {
|
||||||
// float foo [[color(0)]];
|
// float foo [[color(0)]];
|
||||||
|
@ -301,8 +301,8 @@ TEST_F(MslGeneratorImplTest, EmitEntryPointData_Fragment_Output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Compute_Input) {
|
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Compute_Input) {
|
||||||
// [[location 0]] var<in> foo : f32;
|
// [[location(0)]] var<in> foo : f32;
|
||||||
// [[location 1]] var<in> bar : i32;
|
// [[location(1)]] var<in> bar : i32;
|
||||||
//
|
//
|
||||||
// -> Error, not allowed
|
// -> Error, not allowed
|
||||||
|
|
||||||
|
@ -359,8 +359,8 @@ TEST_F(MslGeneratorImplTest, EmitEntryPointData_Compute_Input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Compute_Output) {
|
TEST_F(MslGeneratorImplTest, EmitEntryPointData_Compute_Output) {
|
||||||
// [[location 0]] var<out> foo : f32;
|
// [[location(0)]] var<out> foo : f32;
|
||||||
// [[location 1]] var<out> bar : i32;
|
// [[location(1)]] var<out> bar : i32;
|
||||||
//
|
//
|
||||||
// -> Error not allowed
|
// -> Error not allowed
|
||||||
|
|
||||||
|
@ -420,8 +420,8 @@ TEST_F(MslGeneratorImplTest, EmitEntryPointData_Builtins) {
|
||||||
// Output builtins go in the output struct, input builtins will be passed
|
// Output builtins go in the output struct, input builtins will be passed
|
||||||
// as input parameters to the entry point function.
|
// as input parameters to the entry point function.
|
||||||
|
|
||||||
// [[builtin frag_coord]] var<in> coord : vec4<f32>;
|
// [[builtin(frag_coord)]] var<in> coord : vec4<f32>;
|
||||||
// [[builtin frag_depth]] var<out> depth : f32;
|
// [[builtin(frag_depth)]] var<out> depth : f32;
|
||||||
//
|
//
|
||||||
// struct main_out {
|
// struct main_out {
|
||||||
// float depth [[depth(any)]];
|
// float depth [[depth(any)]];
|
||||||
|
|
|
@ -791,13 +791,13 @@ bool GeneratorImpl::EmitVariableDecorations(ast::DecoratedVariable* var) {
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
if (deco->IsBinding()) {
|
if (deco->IsBinding()) {
|
||||||
out_ << "binding " << deco->AsBinding()->value();
|
out_ << "binding(" << deco->AsBinding()->value() << ")";
|
||||||
} else if (deco->IsSet()) {
|
} else if (deco->IsSet()) {
|
||||||
out_ << "set " << deco->AsSet()->value();
|
out_ << "set(" << deco->AsSet()->value() << ")";
|
||||||
} else if (deco->IsLocation()) {
|
} else if (deco->IsLocation()) {
|
||||||
out_ << "location " << deco->AsLocation()->value();
|
out_ << "location(" << deco->AsLocation()->value() << ")";
|
||||||
} else if (deco->IsBuiltin()) {
|
} else if (deco->IsBuiltin()) {
|
||||||
out_ << "builtin " << deco->AsBuiltin()->value();
|
out_ << "builtin(" << deco->AsBuiltin()->value() << ")";
|
||||||
} else {
|
} else {
|
||||||
error_ = "unknown variable decoration";
|
error_ = "unknown variable decoration";
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -64,7 +64,7 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated) {
|
||||||
|
|
||||||
GeneratorImpl g;
|
GeneratorImpl g;
|
||||||
ASSERT_TRUE(g.EmitVariable(&dv)) << g.error();
|
ASSERT_TRUE(g.EmitVariable(&dv)) << g.error();
|
||||||
EXPECT_EQ(g.result(), R"([[location 2]] var a : f32;
|
EXPECT_EQ(g.result(), R"([[location(2)]] var a : f32;
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +85,9 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated_Multiple) {
|
||||||
|
|
||||||
GeneratorImpl g;
|
GeneratorImpl g;
|
||||||
ASSERT_TRUE(g.EmitVariable(&dv)) << g.error();
|
ASSERT_TRUE(g.EmitVariable(&dv)) << g.error();
|
||||||
EXPECT_EQ(g.result(),
|
EXPECT_EQ(
|
||||||
R"([[builtin position, binding 0, set 1, location 2]] var a : f32;
|
g.result(),
|
||||||
|
R"([[builtin(position), binding(0), set(1), location(2)]] var a : f32;
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@ import "GLSL.std.450" as std;
|
||||||
|
|
||||||
# vertex shader
|
# vertex shader
|
||||||
|
|
||||||
[[location 0]] var<in> a_particlePos : vec2<f32>;
|
[[location(0)]] var<in> a_particlePos : vec2<f32>;
|
||||||
[[location 1]] var<in> a_particleVel : vec2<f32>;
|
[[location(1)]] var<in> a_particleVel : vec2<f32>;
|
||||||
[[location 2]] var<in> a_pos : vec2<f32>;
|
[[location(2)]] var<in> a_pos : vec2<f32>;
|
||||||
[[builtin position]] var<out> gl_Position : vec4<f32>;
|
[[builtin(position)]] var<out> gl_Position : vec4<f32>;
|
||||||
|
|
||||||
fn vtx_main() -> void {
|
fn vtx_main() -> void {
|
||||||
var angle : f32 = -std::atan2(a_particleVel.x, a_particleVel.y);
|
var angle : f32 = -std::atan2(a_particleVel.x, a_particleVel.y);
|
||||||
|
@ -32,7 +32,7 @@ fn vtx_main() -> void {
|
||||||
entry_point vertex as "vert_main" = vtx_main;
|
entry_point vertex as "vert_main" = vtx_main;
|
||||||
|
|
||||||
# fragment shader
|
# fragment shader
|
||||||
[[location 0]] var<out> fragColor : vec4<f32>;
|
[[location(0)]] var<out> fragColor : vec4<f32>;
|
||||||
|
|
||||||
fn frag_main() -> void {
|
fn frag_main() -> void {
|
||||||
fragColor = vec4<f32>(1.0, 1.0, 1.0, 1.0);
|
fragColor = vec4<f32>(1.0, 1.0, 1.0, 1.0);
|
||||||
|
@ -60,11 +60,11 @@ type Particles = [[block]] struct {
|
||||||
[[offset(0)]] particles : [[stride(16)]] array<Particle, 5>;
|
[[offset(0)]] particles : [[stride(16)]] array<Particle, 5>;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[binding 0, set 0]] var<uniform> params : SimParams;
|
[[binding(0), set(0)]] var<uniform> params : SimParams;
|
||||||
[[binding 1, set 0]] var<storage_buffer> particlesA : Particles;
|
[[binding(1), set(0)]] var<storage_buffer> particlesA : Particles;
|
||||||
[[binding 2, set 0]] var<storage_buffer> particlesB : Particles;
|
[[binding(2), set(0)]] var<storage_buffer> particlesB : Particles;
|
||||||
|
|
||||||
[[builtin global_invocation_id]] var<in> gl_GlobalInvocationID : vec3<u32>;
|
[[builtin(global_invocation_id)]] var<in> gl_GlobalInvocationID : vec3<u32>;
|
||||||
|
|
||||||
# https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp
|
# https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp
|
||||||
fn compute_main() -> void {
|
fn compute_main() -> void {
|
||||||
|
|
|
@ -20,12 +20,12 @@ type Uniforms = [[block]] struct {
|
||||||
[[offset(0)]] modelViewProjectionMatrix : mat4x4<f32>;
|
[[offset(0)]] modelViewProjectionMatrix : mat4x4<f32>;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[binding 0, set 0]] var<uniform> uniforms : Uniforms;
|
[[binding(0), set(0)]] var<uniform> uniforms : Uniforms;
|
||||||
|
|
||||||
[[location 0]] var<in> cur_position : vec4<f32>;
|
[[location(0)]] var<in> cur_position : vec4<f32>;
|
||||||
[[location 1]] var<in> color : vec4<f32>;
|
[[location(1)]] var<in> color : vec4<f32>;
|
||||||
[[location 0]] var<out> vtxFragColor : vec4<f32>;
|
[[location(0)]] var<out> vtxFragColor : vec4<f32>;
|
||||||
[[builtin position]] var<out> Position : vec4<f32>;
|
[[builtin(position)]] var<out> Position : vec4<f32>;
|
||||||
|
|
||||||
fn vtx_main() -> void {
|
fn vtx_main() -> void {
|
||||||
Position = uniforms.modelViewProjectionMatrix * cur_position;
|
Position = uniforms.modelViewProjectionMatrix * cur_position;
|
||||||
|
@ -34,8 +34,8 @@ fn vtx_main() -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Fragment shader
|
# Fragment shader
|
||||||
[[location 0]] var<in> fragColor : vec4<f32>;
|
[[location(0)]] var<in> fragColor : vec4<f32>;
|
||||||
[[location 0]] var<out> outColor : vec4<f32>;
|
[[location(0)]] var<out> outColor : vec4<f32>;
|
||||||
|
|
||||||
fn frag_main() -> void {
|
fn frag_main() -> void {
|
||||||
outColor = fragColor;
|
outColor = fragColor;
|
||||||
|
|
|
@ -12,7 +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.
|
||||||
|
|
||||||
[[location 0]] var<out> gl_FragColor : vec4<f32>;
|
[[location(0)]] var<out> gl_FragColor : vec4<f32>;
|
||||||
|
|
||||||
fn bar() -> void {
|
fn bar() -> void {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -18,8 +18,8 @@ const pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
|
||||||
vec2<f32>(-0.5, -0.5),
|
vec2<f32>(-0.5, -0.5),
|
||||||
vec2<f32>(0.5, -0.5));
|
vec2<f32>(0.5, -0.5));
|
||||||
|
|
||||||
[[builtin position]] var<out> Position : vec4<f32>;
|
[[builtin(position)]] var<out> Position : vec4<f32>;
|
||||||
[[builtin vertex_idx]] var<in> VertexIndex : i32;
|
[[builtin(vertex_idx)]] var<in> VertexIndex : i32;
|
||||||
|
|
||||||
fn vtx_main() -> void {
|
fn vtx_main() -> void {
|
||||||
Position = vec4<f32>(pos[VertexIndex], 0.0, 1.0);
|
Position = vec4<f32>(pos[VertexIndex], 0.0, 1.0);
|
||||||
|
@ -28,7 +28,7 @@ fn vtx_main() -> void {
|
||||||
entry_point vertex as "main" = vtx_main;
|
entry_point vertex as "main" = vtx_main;
|
||||||
|
|
||||||
# Fragment shader
|
# Fragment shader
|
||||||
[[location 0]] var<out> outColor : vec4<f32>;
|
[[location(0)]] var<out> outColor : vec4<f32>;
|
||||||
fn frag_main() -> void {
|
fn frag_main() -> void {
|
||||||
outColor = vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
outColor = vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue