[spirv-writer] Add null initializers where needed.
The WGSL spec requires initializers for Output, Private and Function variables. This CL adds initializers where needed. Bug: tint:75 Change-Id: Id97f85a67ead2ffc41d6bdd1b71bf7034b04502a Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/20980 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
5b43c58f02
commit
2287f33424
3
BUILD.gn
3
BUILD.gn
|
@ -268,6 +268,8 @@ source_set("libtint_core_src") {
|
|||
"src/ast/node.h",
|
||||
"src/ast/nop_statement.cc",
|
||||
"src/ast/nop_statement.h",
|
||||
"src/ast/null_literal.cc",
|
||||
"src/ast/null_literal.h",
|
||||
"src/ast/pipeline_stage.cc",
|
||||
"src/ast/pipeline_stage.h",
|
||||
"src/ast/return_statement.cc",
|
||||
|
@ -598,6 +600,7 @@ source_set("tint_unittests_core_src") {
|
|||
"src/ast/member_accessor_expression_test.cc",
|
||||
"src/ast/module_test.cc",
|
||||
"src/ast/nop_statement_test.cc",
|
||||
"src/ast/null_literal_test.cc",
|
||||
"src/ast/return_statement_test.cc",
|
||||
"src/ast/scalar_constructor_expression_test.cc",
|
||||
"src/ast/set_decoration_test.cc",
|
||||
|
|
|
@ -105,6 +105,8 @@ set(TINT_LIB_SRCS
|
|||
ast/node.h
|
||||
ast/nop_statement.cc
|
||||
ast/nop_statement.h
|
||||
ast/null_literal.cc
|
||||
ast/null_literal.h
|
||||
ast/pipeline_stage.cc
|
||||
ast/pipeline_stage.h
|
||||
ast/return_statement.cc
|
||||
|
@ -283,6 +285,7 @@ set(TINT_TEST_SRCS
|
|||
ast/member_accessor_expression_test.cc
|
||||
ast/module_test.cc
|
||||
ast/nop_statement_test.cc
|
||||
ast/null_literal_test.cc
|
||||
ast/binary_expression_test.cc
|
||||
ast/return_statement_test.cc
|
||||
ast/scalar_constructor_expression_test.cc
|
||||
|
|
|
@ -46,6 +46,7 @@ TEST_F(BoolLiteralTest, Is) {
|
|||
EXPECT_FALSE(b.IsInt());
|
||||
EXPECT_FALSE(b.IsFloat());
|
||||
EXPECT_FALSE(b.IsUint());
|
||||
EXPECT_FALSE(b.IsNull());
|
||||
}
|
||||
|
||||
TEST_F(BoolLiteralTest, ToStr) {
|
||||
|
|
|
@ -37,6 +37,7 @@ TEST_F(FloatLiteralTest, Is) {
|
|||
EXPECT_FALSE(f.IsInt());
|
||||
EXPECT_TRUE(f.IsFloat());
|
||||
EXPECT_FALSE(f.IsUint());
|
||||
EXPECT_FALSE(f.IsNull());
|
||||
}
|
||||
|
||||
TEST_F(FloatLiteralTest, ToStr) {
|
||||
|
|
|
@ -38,6 +38,7 @@ TEST_F(IntLiteralTest, Is) {
|
|||
EXPECT_TRUE(i.IsInt());
|
||||
EXPECT_FALSE(i.IsFloat());
|
||||
EXPECT_FALSE(i.IsUint());
|
||||
EXPECT_FALSE(i.IsNull());
|
||||
}
|
||||
|
||||
TEST_F(IntLiteralTest, ToStr) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "src/ast/bool_literal.h"
|
||||
#include "src/ast/float_literal.h"
|
||||
#include "src/ast/int_literal.h"
|
||||
#include "src/ast/null_literal.h"
|
||||
#include "src/ast/uint_literal.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -40,6 +41,10 @@ bool Literal::IsInt() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Literal::IsNull() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Literal::IsUint() const {
|
||||
return false;
|
||||
}
|
||||
|
@ -59,6 +64,11 @@ IntLiteral* Literal::AsInt() {
|
|||
return static_cast<IntLiteral*>(this);
|
||||
}
|
||||
|
||||
NullLiteral* Literal::AsNull() {
|
||||
assert(IsNull());
|
||||
return static_cast<NullLiteral*>(this);
|
||||
}
|
||||
|
||||
UintLiteral* Literal::AsUint() {
|
||||
assert(IsUint());
|
||||
return static_cast<UintLiteral*>(this);
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace ast {
|
|||
class BoolLiteral;
|
||||
class FloatLiteral;
|
||||
class IntLiteral;
|
||||
class NullLiteral;
|
||||
class UintLiteral;
|
||||
|
||||
/// Base class for a literal value
|
||||
|
@ -38,6 +39,8 @@ class Literal {
|
|||
virtual bool IsFloat() const;
|
||||
/// @returns true if this is a signed int literal
|
||||
virtual bool IsInt() const;
|
||||
/// @returns true if this is a null literal
|
||||
virtual bool IsNull() const;
|
||||
/// @returns true if this is a unsigned int literal
|
||||
virtual bool IsUint() const;
|
||||
|
||||
|
@ -47,6 +50,8 @@ class Literal {
|
|||
FloatLiteral* AsFloat();
|
||||
/// @returns the literal as a int literal
|
||||
IntLiteral* AsInt();
|
||||
/// @returns the literal as a null literal
|
||||
NullLiteral* AsNull();
|
||||
/// @returns the literal as a unsigned int literal
|
||||
UintLiteral* AsUint();
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
// 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/null_literal.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
NullLiteral::NullLiteral(ast::type::Type* type) : Literal(type) {}
|
||||
|
||||
NullLiteral::~NullLiteral() = default;
|
||||
|
||||
bool NullLiteral::IsNull() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string NullLiteral::to_str() const {
|
||||
return "null " + type()->type_name();
|
||||
}
|
||||
|
||||
std::string NullLiteral::name() const {
|
||||
return "__null" + type()->type_name();
|
||||
}
|
||||
|
||||
} // namespace ast
|
||||
} // namespace tint
|
|
@ -0,0 +1,46 @@
|
|||
// 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_NULL_LITERAL_H_
|
||||
#define SRC_AST_NULL_LITERAL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/ast/literal.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A null literal
|
||||
class NullLiteral : public Literal {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param type the type
|
||||
NullLiteral(ast::type::Type* type);
|
||||
~NullLiteral() override;
|
||||
|
||||
/// @returns true if this is a null literal
|
||||
bool IsNull() const override;
|
||||
|
||||
/// @returns the name for this literal. This name is unique to this value.
|
||||
std::string name() const override;
|
||||
|
||||
/// @returns the literal as a string
|
||||
std::string to_str() const override;
|
||||
};
|
||||
|
||||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
#endif // SRC_AST_NULL_LITERAL_H_
|
|
@ -0,0 +1,51 @@
|
|||
// 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/null_literal.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/ast/type/i32_type.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
namespace {
|
||||
|
||||
using NullLiteralTest = testing::Test;
|
||||
|
||||
TEST_F(NullLiteralTest, Is) {
|
||||
ast::type::I32Type i32;
|
||||
NullLiteral i{&i32};
|
||||
EXPECT_FALSE(i.IsBool());
|
||||
EXPECT_FALSE(i.IsInt());
|
||||
EXPECT_FALSE(i.IsFloat());
|
||||
EXPECT_FALSE(i.IsUint());
|
||||
EXPECT_TRUE(i.IsNull());
|
||||
}
|
||||
|
||||
TEST_F(NullLiteralTest, ToStr) {
|
||||
ast::type::I32Type i32;
|
||||
NullLiteral i{&i32};
|
||||
|
||||
EXPECT_EQ(i.to_str(), "null __i32");
|
||||
}
|
||||
|
||||
TEST_F(NullLiteralTest, Name_I32) {
|
||||
ast::type::I32Type i32;
|
||||
NullLiteral i{&i32};
|
||||
EXPECT_EQ("__null__i32", i.name());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace ast
|
||||
} // namespace tint
|
|
@ -37,6 +37,7 @@ TEST_F(UintLiteralTest, Is) {
|
|||
EXPECT_FALSE(u.IsInt());
|
||||
EXPECT_FALSE(u.IsFloat());
|
||||
EXPECT_TRUE(u.IsUint());
|
||||
EXPECT_FALSE(u.IsNull());
|
||||
}
|
||||
|
||||
TEST_F(UintLiteralTest, ToStr) {
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "src/ast/location_decoration.h"
|
||||
#include "src/ast/loop_statement.h"
|
||||
#include "src/ast/member_accessor_expression.h"
|
||||
#include "src/ast/null_literal.h"
|
||||
#include "src/ast/return_statement.h"
|
||||
#include "src/ast/scalar_constructor_expression.h"
|
||||
#include "src/ast/set_decoration.h"
|
||||
|
@ -430,9 +431,15 @@ bool Builder::GenerateFunctionVariable(ast::Variable* var) {
|
|||
|
||||
// TODO(dsinclair) We could detect if the constructor is fully const and emit
|
||||
// an initializer value for the variable instead of doing the OpLoad.
|
||||
ast::NullLiteral nl(var->type()->UnwrapPtrIfNeeded());
|
||||
auto null_id = GenerateLiteralIfNeeded(&nl);
|
||||
if (null_id == 0) {
|
||||
return 0;
|
||||
}
|
||||
push_function_var({Operand::Int(type_id), result,
|
||||
Operand::Int(ConvertStorageClass(sc)),
|
||||
Operand::Int(null_id)});
|
||||
|
||||
push_function_var(
|
||||
{Operand::Int(type_id), result, Operand::Int(ConvertStorageClass(sc))});
|
||||
if (var->has_constructor()) {
|
||||
init_id = GenerateLoadIfNeeded(var->constructor()->result_type(), init_id);
|
||||
GenerateStore(var_id, init_id);
|
||||
|
@ -493,6 +500,19 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
|
|||
Operand::Int(ConvertStorageClass(sc))};
|
||||
if (var->has_constructor()) {
|
||||
ops.push_back(Operand::Int(init_id));
|
||||
} else {
|
||||
// If we don't have a constructor and we're an Output or Private variable
|
||||
// then WGSL requires an initializer.
|
||||
if (var->storage_class() == ast::StorageClass::kPrivate ||
|
||||
var->storage_class() == ast::StorageClass::kNone ||
|
||||
var->storage_class() == ast::StorageClass::kOutput) {
|
||||
ast::NullLiteral nl(var->type()->UnwrapPtrIfNeeded());
|
||||
init_id = GenerateLiteralIfNeeded(&nl);
|
||||
if (init_id == 0) {
|
||||
return 0;
|
||||
}
|
||||
ops.push_back(Operand::Int(init_id));
|
||||
}
|
||||
}
|
||||
|
||||
push_type(spv::Op::OpVariable, std::move(ops));
|
||||
|
@ -965,6 +985,8 @@ uint32_t Builder::GenerateLiteralIfNeeded(ast::Literal* lit) {
|
|||
} else if (lit->IsFloat()) {
|
||||
push_type(spv::Op::OpConstant, {Operand::Int(type_id), result,
|
||||
Operand::Float(lit->AsFloat()->value())});
|
||||
} else if (lit->IsNull()) {
|
||||
push_type(spv::Op::OpConstantNull, {Operand::Int(type_id), result});
|
||||
} else {
|
||||
error_ = "unknown literal type";
|
||||
return 0;
|
||||
|
|
|
@ -68,20 +68,21 @@ TEST_F(BuilderTest, ArrayAccessor) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Function %3
|
||||
%5 = OpTypeInt 32 1
|
||||
%6 = OpConstant %5 1
|
||||
%7 = OpTypePointer Function %4
|
||||
%5 = OpConstantNull %3
|
||||
%6 = OpTypeInt 32 1
|
||||
%7 = OpConstant %6 1
|
||||
%8 = OpTypePointer Function %4
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%8 = OpAccessChain %7 %1 %6
|
||||
R"(%9 = OpAccessChain %8 %1 %7
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -114,22 +115,24 @@ TEST_F(BuilderTest, Accessor_Array_LoadIndex) {
|
|||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&idx)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 12u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Function %3
|
||||
%7 = OpTypeInt 32 1
|
||||
%6 = OpTypePointer Function %7
|
||||
%9 = OpTypePointer Function %4
|
||||
%5 = OpConstantNull %3
|
||||
%8 = OpTypeInt 32 1
|
||||
%7 = OpTypePointer Function %8
|
||||
%9 = OpConstantNull %8
|
||||
%11 = OpTypePointer Function %4
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
%5 = OpVariable %6 Function
|
||||
R"(%1 = OpVariable %2 Function %5
|
||||
%6 = OpVariable %7 Function %9
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%8 = OpLoad %7 %5
|
||||
%10 = OpAccessChain %9 %1 %8
|
||||
R"(%10 = OpLoad %8 %6
|
||||
%12 = OpAccessChain %11 %1 %10
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -163,22 +166,23 @@ TEST_F(BuilderTest, ArrayAccessor_Dynamic) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 11u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Function %3
|
||||
%5 = OpTypeInt 32 1
|
||||
%6 = OpConstant %5 1
|
||||
%7 = OpConstant %5 2
|
||||
%9 = OpTypePointer Function %4
|
||||
%5 = OpConstantNull %3
|
||||
%6 = OpTypeInt 32 1
|
||||
%7 = OpConstant %6 1
|
||||
%8 = OpConstant %6 2
|
||||
%10 = OpTypePointer Function %4
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%8 = OpIAdd %5 %6 %7
|
||||
%10 = OpAccessChain %9 %1 %8
|
||||
R"(%9 = OpIAdd %6 %7 %8
|
||||
%11 = OpAccessChain %10 %1 %9
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -211,7 +215,7 @@ TEST_F(BuilderTest, ArrayAccessor_MultiLevel) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 12u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 13u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
|
||||
%4 = OpTypeVector %5 3
|
||||
|
@ -219,16 +223,17 @@ TEST_F(BuilderTest, ArrayAccessor_MultiLevel) {
|
|||
%7 = OpConstant %6 4
|
||||
%3 = OpTypeArray %4 %7
|
||||
%2 = OpTypePointer Function %3
|
||||
%8 = OpTypeInt 32 1
|
||||
%9 = OpConstant %8 3
|
||||
%10 = OpConstant %8 2
|
||||
%11 = OpTypePointer Function %5
|
||||
%8 = OpConstantNull %3
|
||||
%9 = OpTypeInt 32 1
|
||||
%10 = OpConstant %9 3
|
||||
%11 = OpConstant %9 2
|
||||
%12 = OpTypePointer Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %8
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%12 = OpAccessChain %11 %1 %9 %10
|
||||
R"(%13 = OpAccessChain %12 %1 %10 %11
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -259,7 +264,7 @@ TEST_F(BuilderTest, Accessor_ArrayWithSwizzle) {
|
|||
Builder b(&mod);
|
||||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 14u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 15u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
|
||||
%4 = OpTypeVector %5 3
|
||||
|
@ -267,18 +272,19 @@ TEST_F(BuilderTest, Accessor_ArrayWithSwizzle) {
|
|||
%7 = OpConstant %6 4
|
||||
%3 = OpTypeArray %4 %7
|
||||
%2 = OpTypePointer Function %3
|
||||
%8 = OpTypeInt 32 1
|
||||
%9 = OpConstant %8 2
|
||||
%10 = OpTypePointer Function %4
|
||||
%12 = OpTypeVector %5 2
|
||||
%8 = OpConstantNull %3
|
||||
%9 = OpTypeInt 32 1
|
||||
%10 = OpConstant %9 2
|
||||
%11 = OpTypePointer Function %4
|
||||
%13 = OpTypeVector %5 2
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %8
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%11 = OpAccessChain %10 %1 %9
|
||||
%13 = OpLoad %4 %11
|
||||
%14 = OpVectorShuffle %12 %13 %13 0 1
|
||||
R"(%12 = OpAccessChain %11 %1 %10
|
||||
%14 = OpLoad %4 %12
|
||||
%15 = OpVectorShuffle %13 %14 %14 0 1
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -320,20 +326,21 @@ TEST_F(BuilderTest, MemberAccessor) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeStruct %4 %4
|
||||
%2 = OpTypePointer Function %3
|
||||
%5 = OpTypeInt 32 0
|
||||
%6 = OpConstant %5 1
|
||||
%7 = OpTypePointer Function %4
|
||||
%5 = OpConstantNull %3
|
||||
%6 = OpTypeInt 32 0
|
||||
%7 = OpConstant %6 1
|
||||
%8 = OpTypePointer Function %4
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%8 = OpAccessChain %7 %1 %6
|
||||
R"(%9 = OpAccessChain %8 %1 %7
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -385,21 +392,22 @@ TEST_F(BuilderTest, MemberAccessor_Nested) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
|
||||
%4 = OpTypeStruct %5 %5
|
||||
%3 = OpTypeStruct %4
|
||||
%2 = OpTypePointer Function %3
|
||||
%6 = OpTypeInt 32 0
|
||||
%7 = OpConstant %6 0
|
||||
%8 = OpTypePointer Function %5
|
||||
%6 = OpConstantNull %3
|
||||
%7 = OpTypeInt 32 0
|
||||
%8 = OpConstant %7 0
|
||||
%9 = OpTypePointer Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %6
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%9 = OpAccessChain %8 %1 %7 %7
|
||||
R"(%10 = OpAccessChain %9 %1 %8 %8
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -454,21 +462,22 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
|
||||
%4 = OpTypeStruct %5 %5
|
||||
%3 = OpTypeStruct %4
|
||||
%2 = OpTypePointer Function %3
|
||||
%6 = OpTypeInt 32 0
|
||||
%7 = OpConstant %6 0
|
||||
%8 = OpTypePointer Function %5
|
||||
%6 = OpConstantNull %3
|
||||
%7 = OpTypeInt 32 0
|
||||
%8 = OpConstant %7 0
|
||||
%9 = OpTypePointer Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %6
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%9 = OpAccessChain %8 %1 %7 %7
|
||||
R"(%10 = OpAccessChain %9 %1 %8 %8
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -532,17 +541,18 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) {
|
|||
%4 = OpTypeStruct %5 %5
|
||||
%3 = OpTypeStruct %4
|
||||
%2 = OpTypePointer Function %3
|
||||
%6 = OpTypeInt 32 0
|
||||
%7 = OpConstant %6 0
|
||||
%8 = OpTypePointer Function %5
|
||||
%10 = OpConstant %5 2
|
||||
%6 = OpConstantNull %3
|
||||
%7 = OpTypeInt 32 0
|
||||
%8 = OpConstant %7 0
|
||||
%9 = OpTypePointer Function %5
|
||||
%11 = OpConstant %5 2
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %6
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%9 = OpAccessChain %8 %1 %7 %7
|
||||
OpStore %9 %10
|
||||
R"(%10 = OpAccessChain %9 %1 %8 %8
|
||||
OpStore %10 %11
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -608,18 +618,20 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) {
|
|||
%4 = OpTypeStruct %5 %5
|
||||
%3 = OpTypeStruct %4
|
||||
%2 = OpTypePointer Function %3
|
||||
%7 = OpTypePointer Function %5
|
||||
%8 = OpTypeInt 32 0
|
||||
%9 = OpConstant %8 0
|
||||
%6 = OpConstantNull %3
|
||||
%8 = OpTypePointer Function %5
|
||||
%9 = OpConstantNull %5
|
||||
%10 = OpTypeInt 32 0
|
||||
%11 = OpConstant %10 0
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
%6 = OpVariable %7 Function
|
||||
R"(%1 = OpVariable %2 Function %6
|
||||
%7 = OpVariable %8 Function %9
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%10 = OpAccessChain %7 %1 %9 %9
|
||||
%11 = OpLoad %5 %10
|
||||
OpStore %6 %11
|
||||
R"(%12 = OpAccessChain %8 %1 %11 %11
|
||||
%13 = OpLoad %5 %12
|
||||
OpStore %7 %13
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -645,20 +657,21 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_Single) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Function %3
|
||||
%5 = OpTypeInt 32 0
|
||||
%6 = OpConstant %5 1
|
||||
%7 = OpTypePointer Function %4
|
||||
%5 = OpConstantNull %3
|
||||
%6 = OpTypeInt 32 0
|
||||
%7 = OpConstant %6 1
|
||||
%8 = OpTypePointer Function %4
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%8 = OpAccessChain %7 %1 %6
|
||||
R"(%9 = OpAccessChain %8 %1 %7
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -684,19 +697,20 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_MultipleNames) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 7u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Function %3
|
||||
%5 = OpTypeVector %4 2
|
||||
%5 = OpConstantNull %3
|
||||
%6 = OpTypeVector %4 2
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%6 = OpLoad %3 %1
|
||||
%7 = OpVectorShuffle %5 %6 %6 1 0
|
||||
R"(%7 = OpLoad %3 %1
|
||||
%8 = OpVectorShuffle %6 %7 %7 1 0
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -724,20 +738,21 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_of_Swizzle) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Function %3
|
||||
%7 = OpTypeVector %4 2
|
||||
%5 = OpConstantNull %3
|
||||
%8 = OpTypeVector %4 2
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%5 = OpLoad %3 %1
|
||||
%6 = OpVectorShuffle %3 %5 %5 1 0 2
|
||||
%8 = OpVectorShuffle %7 %6 %6 0 2
|
||||
R"(%6 = OpLoad %3 %1
|
||||
%7 = OpVectorShuffle %3 %6 %6 1 0 2
|
||||
%9 = OpVectorShuffle %8 %7 %7 0 2
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -765,19 +780,20 @@ TEST_F(BuilderTest, MemberAccessor_Member_of_Swizzle) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 7u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Function %3
|
||||
%5 = OpConstantNull %3
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%5 = OpLoad %3 %1
|
||||
%6 = OpVectorShuffle %3 %5 %5 1 0 2
|
||||
%7 = OpCompositeExtract %4 %6 0
|
||||
R"(%6 = OpLoad %3 %1
|
||||
%7 = OpVectorShuffle %3 %6 %6 1 0 2
|
||||
%8 = OpCompositeExtract %4 %7 0
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -807,21 +823,22 @@ TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Function %3
|
||||
%7 = OpTypeInt 32 1
|
||||
%8 = OpConstant %7 1
|
||||
%5 = OpConstantNull %3
|
||||
%8 = OpTypeInt 32 1
|
||||
%9 = OpConstant %8 1
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%5 = OpLoad %3 %1
|
||||
%6 = OpVectorShuffle %3 %5 %5 1 0 2
|
||||
%9 = OpVectorExtractDynamic %4 %6 %8
|
||||
R"(%6 = OpLoad %3 %1
|
||||
%7 = OpVectorShuffle %3 %6 %6 1 0 2
|
||||
%10 = OpVectorExtractDynamic %4 %7 %9
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -897,7 +914,7 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 21u);
|
||||
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 22u);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%9 = OpTypeFloat 32
|
||||
%8 = OpTypeVector %9 3
|
||||
|
@ -910,20 +927,21 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
|
|||
%12 = OpConstant %10 2
|
||||
%3 = OpTypeArray %4 %12
|
||||
%2 = OpTypePointer Function %3
|
||||
%13 = OpTypeInt 32 1
|
||||
%14 = OpConstant %13 0
|
||||
%15 = OpConstant %10 0
|
||||
%16 = OpConstant %13 2
|
||||
%17 = OpTypePointer Function %8
|
||||
%19 = OpTypeVector %9 2
|
||||
%13 = OpConstantNull %3
|
||||
%14 = OpTypeInt 32 1
|
||||
%15 = OpConstant %14 0
|
||||
%16 = OpConstant %10 0
|
||||
%17 = OpConstant %14 2
|
||||
%18 = OpTypePointer Function %8
|
||||
%20 = OpTypeVector %9 2
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %13
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%18 = OpAccessChain %17 %1 %14 %15 %16 %15 %15
|
||||
%20 = OpLoad %8 %18
|
||||
%21 = OpVectorShuffle %19 %20 %20 1 0
|
||||
R"(%19 = OpAccessChain %18 %1 %15 %16 %17 %16 %16
|
||||
%21 = OpLoad %8 %19
|
||||
%22 = OpVectorShuffle %20 %21 %21 1 0
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
|
@ -69,11 +69,12 @@ TEST_F(BuilderTest, Assign_Var) {
|
|||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Output %3
|
||||
%1 = OpVariable %2 Output
|
||||
%4 = OpConstant %3 1
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Output %4
|
||||
%5 = OpConstant %3 1
|
||||
)");
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %4
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %5
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -180,13 +181,14 @@ TEST_F(BuilderTest, Assign_Vector) {
|
|||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Output %3
|
||||
%1 = OpVariable %2 Output
|
||||
%5 = OpConstant %4 1
|
||||
%6 = OpConstant %4 3
|
||||
%7 = OpConstantComposite %3 %5 %5 %6
|
||||
%5 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Output %5
|
||||
%6 = OpConstant %4 1
|
||||
%7 = OpConstant %4 3
|
||||
%8 = OpConstantComposite %3 %6 %6 %7
|
||||
)");
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %7
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %8
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -224,16 +226,17 @@ TEST_F(BuilderTest, Assign_Vector_MemberByName) {
|
|||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Output %3
|
||||
%1 = OpVariable %2 Output
|
||||
%5 = OpTypeInt 32 0
|
||||
%6 = OpConstant %5 1
|
||||
%7 = OpTypePointer Output %4
|
||||
%9 = OpConstant %4 1
|
||||
%5 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Output %5
|
||||
%6 = OpTypeInt 32 0
|
||||
%7 = OpConstant %6 1
|
||||
%8 = OpTypePointer Output %4
|
||||
%10 = OpConstant %4 1
|
||||
)");
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%8 = OpAccessChain %7 %1 %6
|
||||
OpStore %8 %9
|
||||
R"(%9 = OpAccessChain %8 %1 %7
|
||||
OpStore %9 %10
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -273,16 +276,17 @@ TEST_F(BuilderTest, Assign_Vector_MemberByIndex) {
|
|||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Output %3
|
||||
%1 = OpVariable %2 Output
|
||||
%5 = OpTypeInt 32 1
|
||||
%6 = OpConstant %5 1
|
||||
%7 = OpTypePointer Output %4
|
||||
%9 = OpConstant %4 1
|
||||
%5 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Output %5
|
||||
%6 = OpTypeInt 32 1
|
||||
%7 = OpConstant %6 1
|
||||
%8 = OpTypePointer Output %4
|
||||
%10 = OpConstant %4 1
|
||||
)");
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%8 = OpAccessChain %7 %1 %6
|
||||
OpStore %8 %9
|
||||
R"(%9 = OpAccessChain %8 %1 %7
|
||||
OpStore %9 %10
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
|
@ -107,19 +107,20 @@ TEST_F(BuilderTest, Call_GLSLMethod_WithLoad) {
|
|||
ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
|
||||
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateCallExpression(&expr), 9u) << b.error();
|
||||
EXPECT_EQ(b.GenerateCallExpression(&expr), 10u) << b.error();
|
||||
EXPECT_EQ(DumpBuilder(b), R"(%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %2 "ident"
|
||||
OpName %7 "a_func"
|
||||
OpName %8 "a_func"
|
||||
%4 = OpTypeFloat 32
|
||||
%3 = OpTypePointer Private %4
|
||||
%2 = OpVariable %3 Private
|
||||
%6 = OpTypeVoid
|
||||
%5 = OpTypeFunction %6
|
||||
%7 = OpFunction %6 None %5
|
||||
%8 = OpLabel
|
||||
%10 = OpLoad %4 %2
|
||||
%9 = OpExtInst %4 %1 Round %10
|
||||
%5 = OpConstantNull %4
|
||||
%2 = OpVariable %3 Private %5
|
||||
%7 = OpTypeVoid
|
||||
%6 = OpTypeFunction %7
|
||||
%8 = OpFunction %7 None %6
|
||||
%9 = OpLabel
|
||||
%11 = OpLoad %4 %2
|
||||
%10 = OpExtInst %4 %1 Round %11
|
||||
OpFunctionEnd
|
||||
)");
|
||||
}
|
||||
|
|
|
@ -86,16 +86,17 @@ TEST_F(BuilderTest, Cast_WithLoad) {
|
|||
Builder b(&mod);
|
||||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error();
|
||||
EXPECT_EQ(b.GenerateCastExpression(&cast), 4u) << b.error();
|
||||
EXPECT_EQ(b.GenerateCastExpression(&cast), 5u) << b.error();
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Private %3
|
||||
%1 = OpVariable %2 Private
|
||||
%5 = OpTypeFloat 32
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
%6 = OpTypeFloat 32
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%6 = OpLoad %3 %1
|
||||
%4 = OpConvertSToF %5 %6
|
||||
R"(%7 = OpLoad %3 %1
|
||||
%5 = OpConvertSToF %6 %7
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
|
@ -106,21 +106,22 @@ TEST_F(BuilderTest, Constructor_Type_NonConstructorParam) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(var.get())) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateConstructorExpression(&t, false), 7u);
|
||||
EXPECT_EQ(b.GenerateConstructorExpression(&t, false), 8u);
|
||||
ASSERT_FALSE(b.has_error()) << b.error();
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Function %3
|
||||
%4 = OpTypeVector %3 2
|
||||
%5 = OpConstant %3 1
|
||||
%4 = OpConstantNull %3
|
||||
%5 = OpTypeVector %3 2
|
||||
%6 = OpConstant %3 1
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %4
|
||||
)");
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%6 = OpLoad %3 %1
|
||||
%7 = OpCompositeConstruct %4 %5 %6
|
||||
R"(%7 = OpLoad %3 %1
|
||||
%8 = OpCompositeConstruct %5 %6 %7
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -151,24 +152,25 @@ TEST_F(BuilderTest, Constructor_Type_NonConstVector) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateFunctionVariable(var.get())) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateConstructorExpression(&t, false), 10u);
|
||||
EXPECT_EQ(b.GenerateConstructorExpression(&t, false), 11u);
|
||||
ASSERT_FALSE(b.has_error()) << b.error();
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
|
||||
%3 = OpTypeVector %4 2
|
||||
%2 = OpTypePointer Function %3
|
||||
%5 = OpTypeVector %4 4
|
||||
%6 = OpConstant %4 1
|
||||
%5 = OpConstantNull %3
|
||||
%6 = OpTypeVector %4 4
|
||||
%7 = OpConstant %4 1
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%1 = OpVariable %2 Function
|
||||
R"(%1 = OpVariable %2 Function %5
|
||||
)");
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%7 = OpLoad %3 %1
|
||||
%8 = OpCompositeExtract %4 %7 0
|
||||
%9 = OpCompositeExtract %4 %7 1
|
||||
%10 = OpCompositeConstruct %5 %6 %6 %8 %9
|
||||
R"(%8 = OpLoad %3 %1
|
||||
%9 = OpCompositeExtract %4 %8 0
|
||||
%10 = OpCompositeExtract %4 %8 1
|
||||
%11 = OpCompositeConstruct %6 %7 %7 %9 %10
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
|
@ -129,15 +129,16 @@ TEST_F(BuilderTest, EntryPoint_WithInterfaceIds) {
|
|||
ASSERT_TRUE(b.GenerateEntryPoint(&ep));
|
||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in"
|
||||
OpName %4 "my_out"
|
||||
OpName %6 "my_wg"
|
||||
OpName %7 "my_wg"
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Input %3
|
||||
%1 = OpVariable %2 Input
|
||||
%5 = OpTypePointer Output %3
|
||||
%4 = OpVariable %5 Output
|
||||
%7 = OpTypePointer Workgroup %3
|
||||
%6 = OpVariable %7 Workgroup
|
||||
%6 = OpConstantNull %3
|
||||
%4 = OpVariable %5 Output %6
|
||||
%8 = OpTypePointer Workgroup %3
|
||||
%7 = OpVariable %8 Workgroup
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.preamble()),
|
||||
R"(OpEntryPoint Vertex %3 "main" %1 %4
|
||||
|
|
|
@ -54,10 +54,12 @@ TEST_F(BuilderTest, FunctionVar_NoStorageClass) {
|
|||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Function %3
|
||||
%4 = OpConstantNull %3
|
||||
)");
|
||||
|
||||
const auto& func = b.functions()[0];
|
||||
EXPECT_EQ(DumpInstructions(func.variables()), R"(%1 = OpVariable %2 Function
|
||||
EXPECT_EQ(DumpInstructions(func.variables()),
|
||||
R"(%1 = OpVariable %2 Function %4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -99,9 +101,10 @@ TEST_F(BuilderTest, FunctionVar_WithConstantConstructor) {
|
|||
%4 = OpConstant %2 3
|
||||
%5 = OpConstantComposite %1 %3 %3 %4
|
||||
%7 = OpTypePointer Function %2
|
||||
%8 = OpConstantNull %2
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%6 = OpVariable %7 Function
|
||||
R"(%6 = OpVariable %7 Function %8
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %6 %5
|
||||
)");
|
||||
|
@ -147,9 +150,10 @@ TEST_F(BuilderTest, FunctionVar_WithNonConstantConstructor) {
|
|||
%3 = OpConstant %2 1
|
||||
%4 = OpConstant %2 3
|
||||
%8 = OpTypePointer Function %1
|
||||
%9 = OpConstantNull %1
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
|
||||
R"(%7 = OpVariable %8 Function
|
||||
R"(%7 = OpVariable %8 Function %9
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%5 = OpFAdd %2 %4 %4
|
||||
|
|
|
@ -52,7 +52,8 @@ TEST_F(BuilderTest, GlobalVar_NoStorageClass) {
|
|||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Private %3
|
||||
%1 = OpVariable %2 Private
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -67,7 +68,23 @@ TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
|
|||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Output %3
|
||||
%1 = OpVariable %2 Output
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Output %4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(BuilderTest, GlobalVar_WithStorageClass_Input) {
|
||||
ast::type::F32Type f32;
|
||||
ast::Variable v("var", ast::StorageClass::kInput, &f32);
|
||||
|
||||
ast::Module mod;
|
||||
Builder b(&mod);
|
||||
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Input %3
|
||||
%1 = OpVariable %2 Input
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -167,7 +184,8 @@ TEST_F(BuilderTest, GlobalVar_WithLocation) {
|
|||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Output %3
|
||||
%1 = OpVariable %2 Output
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Output %4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -192,7 +210,8 @@ OpDecorate %1 DescriptorSet 3
|
|||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Output %3
|
||||
%1 = OpVariable %2 Output
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Output %4
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -216,7 +235,8 @@ TEST_F(BuilderTest, GlobalVar_WithBuiltin) {
|
|||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Output %3
|
||||
%1 = OpVariable %2 Output
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Output %4
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,8 @@ TEST_F(BuilderTest, IdentifierExpression_GlobalVar) {
|
|||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Output %3
|
||||
%1 = OpVariable %2 Output
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Output %4
|
||||
)");
|
||||
|
||||
ast::IdentifierExpression expr("var");
|
||||
|
@ -161,10 +162,12 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
|
|||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||
%2 = OpTypePointer Function %3
|
||||
%4 = OpConstantNull %3
|
||||
)");
|
||||
|
||||
const auto& func = b.functions()[0];
|
||||
EXPECT_EQ(DumpInstructions(func.variables()), R"(%1 = OpVariable %2 Function
|
||||
EXPECT_EQ(DumpInstructions(func.variables()),
|
||||
R"(%1 = OpVariable %2 Function %4
|
||||
)");
|
||||
|
||||
ast::IdentifierExpression expr("var");
|
||||
|
@ -195,15 +198,16 @@ TEST_F(BuilderTest, IdentifierExpression_Load) {
|
|||
b.push_function(Function{});
|
||||
ASSERT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
|
||||
|
||||
EXPECT_EQ(b.GenerateBinaryExpression(&expr), 6u) << b.error();
|
||||
EXPECT_EQ(b.GenerateBinaryExpression(&expr), 7u) << b.error();
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Private %3
|
||||
%1 = OpVariable %2 Private
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%4 = OpLoad %3 %1
|
||||
%5 = OpLoad %3 %1
|
||||
%6 = OpIAdd %3 %4 %5
|
||||
R"(%5 = OpLoad %3 %1
|
||||
%6 = OpLoad %3 %1
|
||||
%7 = OpIAdd %3 %5 %6
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
|
@ -107,18 +107,19 @@ TEST_F(BuilderTest, If_WithStatements) {
|
|||
EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error();
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Private %3
|
||||
%1 = OpVariable %2 Private
|
||||
%4 = OpTypeBool
|
||||
%5 = OpConstantTrue %4
|
||||
%8 = OpConstant %3 2
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
%5 = OpTypeBool
|
||||
%6 = OpConstantTrue %5
|
||||
%9 = OpConstant %3 2
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(OpSelectionMerge %6 None
|
||||
OpBranchConditional %5 %7 %6
|
||||
R"(OpSelectionMerge %7 None
|
||||
OpBranchConditional %6 %8 %7
|
||||
%8 = OpLabel
|
||||
OpStore %1 %9
|
||||
OpBranch %7
|
||||
%7 = OpLabel
|
||||
OpStore %1 %8
|
||||
OpBranch %6
|
||||
%6 = OpLabel
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -170,22 +171,23 @@ TEST_F(BuilderTest, If_WithElse) {
|
|||
EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error();
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Private %3
|
||||
%1 = OpVariable %2 Private
|
||||
%4 = OpTypeBool
|
||||
%5 = OpConstantTrue %4
|
||||
%9 = OpConstant %3 2
|
||||
%10 = OpConstant %3 3
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
%5 = OpTypeBool
|
||||
%6 = OpConstantTrue %5
|
||||
%10 = OpConstant %3 2
|
||||
%11 = OpConstant %3 3
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(OpSelectionMerge %6 None
|
||||
OpBranchConditional %5 %7 %8
|
||||
%7 = OpLabel
|
||||
OpStore %1 %9
|
||||
OpBranch %6
|
||||
R"(OpSelectionMerge %7 None
|
||||
OpBranchConditional %6 %8 %9
|
||||
%8 = OpLabel
|
||||
OpStore %1 %10
|
||||
OpBranch %6
|
||||
%6 = OpLabel
|
||||
OpBranch %7
|
||||
%9 = OpLabel
|
||||
OpStore %1 %11
|
||||
OpBranch %7
|
||||
%7 = OpLabel
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -240,27 +242,28 @@ TEST_F(BuilderTest, If_WithElseIf) {
|
|||
EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error();
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Private %3
|
||||
%1 = OpVariable %2 Private
|
||||
%4 = OpTypeBool
|
||||
%5 = OpConstantTrue %4
|
||||
%9 = OpConstant %3 2
|
||||
%12 = OpConstant %3 3
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
%5 = OpTypeBool
|
||||
%6 = OpConstantTrue %5
|
||||
%10 = OpConstant %3 2
|
||||
%13 = OpConstant %3 3
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(OpSelectionMerge %6 None
|
||||
OpBranchConditional %5 %7 %8
|
||||
%7 = OpLabel
|
||||
OpStore %1 %9
|
||||
OpBranch %6
|
||||
R"(OpSelectionMerge %7 None
|
||||
OpBranchConditional %6 %8 %9
|
||||
%8 = OpLabel
|
||||
OpSelectionMerge %10 None
|
||||
OpBranchConditional %5 %11 %10
|
||||
OpStore %1 %10
|
||||
OpBranch %7
|
||||
%9 = OpLabel
|
||||
OpSelectionMerge %11 None
|
||||
OpBranchConditional %6 %12 %11
|
||||
%12 = OpLabel
|
||||
OpStore %1 %13
|
||||
OpBranch %11
|
||||
%11 = OpLabel
|
||||
OpStore %1 %12
|
||||
OpBranch %10
|
||||
%10 = OpLabel
|
||||
OpBranch %6
|
||||
%6 = OpLabel
|
||||
OpBranch %7
|
||||
%7 = OpLabel
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -334,41 +337,42 @@ TEST_F(BuilderTest, If_WithMultiple) {
|
|||
EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error();
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Private %3
|
||||
%1 = OpVariable %2 Private
|
||||
%4 = OpTypeBool
|
||||
%5 = OpConstantTrue %4
|
||||
%9 = OpConstant %3 2
|
||||
%13 = OpConstant %3 3
|
||||
%14 = OpConstantFalse %4
|
||||
%18 = OpConstant %3 4
|
||||
%19 = OpConstant %3 5
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
%5 = OpTypeBool
|
||||
%6 = OpConstantTrue %5
|
||||
%10 = OpConstant %3 2
|
||||
%14 = OpConstant %3 3
|
||||
%15 = OpConstantFalse %5
|
||||
%19 = OpConstant %3 4
|
||||
%20 = OpConstant %3 5
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(OpSelectionMerge %6 None
|
||||
OpBranchConditional %5 %7 %8
|
||||
%7 = OpLabel
|
||||
OpStore %1 %9
|
||||
OpBranch %6
|
||||
R"(OpSelectionMerge %7 None
|
||||
OpBranchConditional %6 %8 %9
|
||||
%8 = OpLabel
|
||||
OpSelectionMerge %10 None
|
||||
OpBranchConditional %5 %11 %12
|
||||
%11 = OpLabel
|
||||
OpStore %1 %13
|
||||
OpBranch %10
|
||||
OpStore %1 %10
|
||||
OpBranch %7
|
||||
%9 = OpLabel
|
||||
OpSelectionMerge %11 None
|
||||
OpBranchConditional %6 %12 %13
|
||||
%12 = OpLabel
|
||||
OpSelectionMerge %15 None
|
||||
OpBranchConditional %14 %16 %17
|
||||
%16 = OpLabel
|
||||
OpStore %1 %18
|
||||
OpBranch %15
|
||||
OpStore %1 %14
|
||||
OpBranch %11
|
||||
%13 = OpLabel
|
||||
OpSelectionMerge %16 None
|
||||
OpBranchConditional %15 %17 %18
|
||||
%17 = OpLabel
|
||||
OpStore %1 %19
|
||||
OpBranch %15
|
||||
%15 = OpLabel
|
||||
OpBranch %10
|
||||
%10 = OpLabel
|
||||
OpBranch %6
|
||||
%6 = OpLabel
|
||||
OpBranch %16
|
||||
%18 = OpLabel
|
||||
OpStore %1 %20
|
||||
OpBranch %16
|
||||
%16 = OpLabel
|
||||
OpBranch %11
|
||||
%11 = OpLabel
|
||||
OpBranch %7
|
||||
%7 = OpLabel
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
|
@ -94,20 +94,21 @@ TEST_F(BuilderTest, Loop_WithoutContinuing) {
|
|||
EXPECT_TRUE(b.GenerateLoopStatement(&expr)) << b.error();
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Private %3
|
||||
%1 = OpVariable %2 Private
|
||||
%8 = OpConstant %3 2
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
%9 = OpConstant %3 2
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(OpBranch %4
|
||||
%4 = OpLabel
|
||||
OpLoopMerge %5 %6 None
|
||||
R"(OpBranch %5
|
||||
%5 = OpLabel
|
||||
OpLoopMerge %6 %7 None
|
||||
OpBranch %8
|
||||
%8 = OpLabel
|
||||
OpStore %1 %9
|
||||
OpBranch %7
|
||||
%7 = OpLabel
|
||||
OpStore %1 %8
|
||||
OpBranch %6
|
||||
OpBranch %5
|
||||
%6 = OpLabel
|
||||
OpBranch %4
|
||||
%5 = OpLabel
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -149,22 +150,23 @@ TEST_F(BuilderTest, Loop_WithContinuing) {
|
|||
EXPECT_TRUE(b.GenerateLoopStatement(&expr)) << b.error();
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Private %3
|
||||
%1 = OpVariable %2 Private
|
||||
%8 = OpConstant %3 2
|
||||
%9 = OpConstant %3 3
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
%9 = OpConstant %3 2
|
||||
%10 = OpConstant %3 3
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(OpBranch %4
|
||||
%4 = OpLabel
|
||||
OpLoopMerge %5 %6 None
|
||||
R"(OpBranch %5
|
||||
%5 = OpLabel
|
||||
OpLoopMerge %6 %7 None
|
||||
OpBranch %8
|
||||
%8 = OpLabel
|
||||
OpStore %1 %9
|
||||
OpBranch %7
|
||||
%7 = OpLabel
|
||||
OpStore %1 %8
|
||||
OpBranch %6
|
||||
OpStore %1 %10
|
||||
OpBranch %5
|
||||
%6 = OpLabel
|
||||
OpStore %1 %9
|
||||
OpBranch %4
|
||||
%5 = OpLabel
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue