resolver: Implement element inference of vecN and matNxM
Fixed: tint:1334 Change-Id: Idc94d49ecd41e37354bb93138348e3af3e733932 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/72143 Reviewed-by: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
f91b02bba1
commit
81b3948649
|
@ -14,6 +14,7 @@
|
|||
|
||||
### New Features
|
||||
|
||||
* Vector and matrix element type can now be inferred from constructor argument types. [tint:1334](https://crbug.com/tint/1334)
|
||||
* New texture gather builtins: `textureGather()` and `textureGatherCompare()`. [tint:1330](https://crbug.com/tint/1330)
|
||||
* Shadowing is now fully supported. [tint:819](https://crbug.com/tint/819)
|
||||
* The `dot()` builtin now supports integer vector types.
|
||||
|
|
|
@ -28,7 +28,9 @@ class Matrix : public Castable<Matrix, Type> {
|
|||
/// Constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param subtype type matrix type
|
||||
/// @param subtype the declared type of the matrix components. May be null for
|
||||
/// matrix constructors, where the element type will be inferred from
|
||||
/// the constructor arguments
|
||||
/// @param rows the number of rows in the matrix
|
||||
/// @param columns the number of columns in the matrix
|
||||
Matrix(ProgramID pid,
|
||||
|
@ -50,7 +52,9 @@ class Matrix : public Castable<Matrix, Type> {
|
|||
/// @return the newly cloned type
|
||||
const Matrix* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The type of the matrix
|
||||
/// The declared type of the matrix components. May be null for matrix
|
||||
/// constructors, where the element type will be inferred from the constructor
|
||||
/// arguments
|
||||
const Type* const type;
|
||||
|
||||
/// The number of rows in the matrix
|
||||
|
|
|
@ -37,7 +37,10 @@ Vector::~Vector() = default;
|
|||
|
||||
std::string Vector::FriendlyName(const SymbolTable& symbols) const {
|
||||
std::ostringstream out;
|
||||
out << "vec" << width << "<" << type->FriendlyName(symbols) << ">";
|
||||
out << "vec" << width;
|
||||
if (type) {
|
||||
out << "<" << type->FriendlyName(symbols) << ">";
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,9 @@ class Vector : public Castable<Vector, Type> {
|
|||
/// Constructor
|
||||
/// @param pid the identifier of the program that owns this node
|
||||
/// @param src the source of this node
|
||||
/// @param subtype the vector element type
|
||||
/// @param subtype the declared type of the vector components. May be null
|
||||
/// for vector constructors, where the element type will be inferred
|
||||
/// from the constructor arguments
|
||||
/// @param width the number of elements in the vector
|
||||
Vector(ProgramID pid, Source const& src, const Type* subtype, uint32_t width);
|
||||
/// Move constructor
|
||||
|
@ -45,7 +47,9 @@ class Vector : public Castable<Vector, Type> {
|
|||
/// @return the newly cloned type
|
||||
const Vector* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The type of the vector elements
|
||||
/// The declared type of the vector components. May be null for vector
|
||||
/// constructors, where the element type will be inferred from the constructor
|
||||
/// arguments
|
||||
const Type* const type;
|
||||
|
||||
/// The number of elements in the vector
|
||||
|
|
|
@ -1154,19 +1154,23 @@ Expect<const ast::Type*> ParserImpl::expect_type_decl_atomic(Token t) {
|
|||
|
||||
Expect<const ast::Type*> ParserImpl::expect_type_decl_vector(Token t) {
|
||||
uint32_t count = 2;
|
||||
if (t.Is(Token::Type::kVec3))
|
||||
if (t.Is(Token::Type::kVec3)) {
|
||||
count = 3;
|
||||
else if (t.Is(Token::Type::kVec4))
|
||||
} else if (t.Is(Token::Type::kVec4)) {
|
||||
count = 4;
|
||||
}
|
||||
|
||||
const char* use = "vector";
|
||||
const ast::Type* subtype = nullptr;
|
||||
if (peek_is(Token::Type::kLessThan)) {
|
||||
const char* use = "vector";
|
||||
auto ty = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
||||
if (ty.errored) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
subtype = ty.value;
|
||||
}
|
||||
|
||||
auto subtype = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
||||
if (subtype.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return builder_.ty.vec(make_source_range_from(t.source()), subtype.value,
|
||||
count);
|
||||
return builder_.ty.vec(make_source_range_from(t.source()), subtype, count);
|
||||
}
|
||||
|
||||
Expect<const ast::Type*> ParserImpl::expect_type_decl_array(
|
||||
|
@ -1217,14 +1221,18 @@ Expect<const ast::Type*> ParserImpl::expect_type_decl_matrix(Token t) {
|
|||
rows = 4;
|
||||
}
|
||||
|
||||
const char* use = "matrix";
|
||||
const ast::Type* subtype = nullptr;
|
||||
if (peek_is(Token::Type::kLessThan)) {
|
||||
const char* use = "matrix";
|
||||
auto ty = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
||||
if (ty.errored) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
subtype = ty.value;
|
||||
}
|
||||
|
||||
auto subtype = expect_lt_gt_block(use, [&] { return expect_type(use); });
|
||||
if (subtype.errored)
|
||||
return Failure::kErrored;
|
||||
|
||||
return builder_.ty.mat(make_source_range_from(t.source()), subtype.value,
|
||||
columns, rows);
|
||||
return builder_.ty.mat(make_source_range_from(t.source()), subtype, columns,
|
||||
rows);
|
||||
}
|
||||
|
||||
// storage_class
|
||||
|
|
|
@ -975,13 +975,6 @@ TEST_F(ParserImplErrorTest, GlobalDeclVarInvalidIdentifier) {
|
|||
" ^\n");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarMatrixMissingLessThan) {
|
||||
EXPECT("var i : mat4x4;",
|
||||
"test.wgsl:1:15 error: expected '<' for matrix\n"
|
||||
"var i : mat4x4;\n"
|
||||
" ^\n");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarMatrixMissingGreaterThan) {
|
||||
EXPECT("var i : mat4x4<u32;",
|
||||
"test.wgsl:1:19 error: expected '>' for matrix\n"
|
||||
|
@ -1066,13 +1059,6 @@ TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclMissingGThan) {
|
|||
" ^\n");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarVectorMissingLessThan) {
|
||||
EXPECT("var i : vec3;",
|
||||
"test.wgsl:1:13 error: expected '<' for vector\n"
|
||||
"var i : vec3;\n"
|
||||
" ^\n");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarVectorMissingGreaterThan) {
|
||||
EXPECT("var i : vec3<u32;",
|
||||
"test.wgsl:1:17 error: expected '>' for vector\n"
|
||||
|
|
|
@ -139,24 +139,6 @@ INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
|||
VecData{"vec3<f32", 3, {}},
|
||||
VecData{"vec4<f32", 4, {}}));
|
||||
|
||||
class VecMissingLessThanTest : public ParserImplTestWithParam<VecData> {};
|
||||
|
||||
TEST_P(VecMissingLessThanTest, Handles_Missing_GreaterThan) {
|
||||
auto params = GetParam();
|
||||
auto p = parser(params.input);
|
||||
auto t = p->type_decl();
|
||||
EXPECT_TRUE(t.errored);
|
||||
EXPECT_FALSE(t.matched);
|
||||
ASSERT_EQ(t.value, nullptr);
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(p->error(), "1:5: expected '<' for vector");
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
||||
VecMissingLessThanTest,
|
||||
testing::Values(VecData{"vec2", 2, {}},
|
||||
VecData{"vec3", 3, {}},
|
||||
VecData{"vec4", 4, {}}));
|
||||
|
||||
class VecMissingType : public ParserImplTestWithParam<VecData> {};
|
||||
|
||||
TEST_P(VecMissingType, Handles_Missing_Type) {
|
||||
|
@ -774,30 +756,6 @@ INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
|||
MatrixData{"mat4x3<f32", 4, 3, {}},
|
||||
MatrixData{"mat4x4<f32", 4, 4, {}}));
|
||||
|
||||
class MatrixMissingLessThanTest : public ParserImplTestWithParam<MatrixData> {};
|
||||
|
||||
TEST_P(MatrixMissingLessThanTest, Handles_Missing_GreaterThan) {
|
||||
auto params = GetParam();
|
||||
auto p = parser(params.input);
|
||||
auto t = p->type_decl();
|
||||
EXPECT_TRUE(t.errored);
|
||||
EXPECT_FALSE(t.matched);
|
||||
ASSERT_EQ(t.value, nullptr);
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(p->error(), "1:8: expected '<' for matrix");
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
|
||||
MatrixMissingLessThanTest,
|
||||
testing::Values(MatrixData{"mat2x2 f32>", 2, 2, {}},
|
||||
MatrixData{"mat2x3 f32>", 2, 3, {}},
|
||||
MatrixData{"mat2x4 f32>", 2, 4, {}},
|
||||
MatrixData{"mat3x2 f32>", 3, 2, {}},
|
||||
MatrixData{"mat3x3 f32>", 3, 3, {}},
|
||||
MatrixData{"mat3x4 f32>", 3, 4, {}},
|
||||
MatrixData{"mat4x2 f32>", 4, 2, {}},
|
||||
MatrixData{"mat4x3 f32>", 4, 3, {}},
|
||||
MatrixData{"mat4x4 f32>", 4, 4, {}}));
|
||||
|
||||
class MatrixMissingType : public ParserImplTestWithParam<MatrixData> {};
|
||||
|
||||
TEST_P(MatrixMissingType, Handles_Missing_Type) {
|
||||
|
|
|
@ -766,6 +766,28 @@ TEST_F(ResolverFunctionValidationTest, ParametersOverLimit) {
|
|||
"12:34 error: functions may declare at most 255 parameters");
|
||||
}
|
||||
|
||||
TEST_F(ResolverFunctionValidationTest, ParameterVectorNoType) {
|
||||
// fn f(p : vec3) {}
|
||||
|
||||
Func(Source{{12, 34}}, "f",
|
||||
{Param("p", create<ast::Vector>(Source{{12, 34}}, nullptr, 3))},
|
||||
ty.void_(), {});
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverFunctionValidationTest, ParameterMatrixNoType) {
|
||||
// fn f(p : vec3) {}
|
||||
|
||||
Func(Source{{12, 34}}, "f",
|
||||
{Param("p", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3, 3))},
|
||||
ty.void_(), {});
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
|
||||
}
|
||||
|
||||
struct TestParams {
|
||||
ast::StorageClass storage_class;
|
||||
bool should_pass;
|
||||
|
|
|
@ -180,6 +180,10 @@ sem::Type* Resolver::Type(const ast::Type* ty) {
|
|||
return builder_->create<sem::F32>();
|
||||
}
|
||||
if (auto* t = ty->As<ast::Vector>()) {
|
||||
if (!t->type) {
|
||||
AddError("missing vector element type", t->source.End());
|
||||
return nullptr;
|
||||
}
|
||||
if (auto* el = Type(t->type)) {
|
||||
if (auto* vector = builder_->create<sem::Vector>(el, t->width)) {
|
||||
if (ValidateVector(vector, t->source)) {
|
||||
|
@ -190,6 +194,10 @@ sem::Type* Resolver::Type(const ast::Type* ty) {
|
|||
return nullptr;
|
||||
}
|
||||
if (auto* t = ty->As<ast::Matrix>()) {
|
||||
if (!t->type) {
|
||||
AddError("missing matrix element type", t->source.End());
|
||||
return nullptr;
|
||||
}
|
||||
if (auto* el = Type(t->type)) {
|
||||
if (auto* column_type = builder_->create<sem::Vector>(el, t->rows)) {
|
||||
if (auto* matrix =
|
||||
|
@ -1240,6 +1248,10 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
|||
std::vector<const sem::Type*> arg_tys(args.size());
|
||||
sem::Behaviors arg_behaviors;
|
||||
|
||||
// The element type of all the arguments. Nullptr if argument types are
|
||||
// different.
|
||||
const sem::Type* arg_el_ty = nullptr;
|
||||
|
||||
for (size_t i = 0; i < expr->args.size(); i++) {
|
||||
auto* arg = Sem(expr->args[i]);
|
||||
if (!arg) {
|
||||
|
@ -1248,6 +1260,19 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
|||
args[i] = arg;
|
||||
arg_tys[i] = args[i]->Type();
|
||||
arg_behaviors.Add(arg->Behaviors());
|
||||
|
||||
// Determine the common argument element type
|
||||
auto* el_ty = arg_tys[i]->UnwrapRef();
|
||||
if (auto* vec = el_ty->As<sem::Vector>()) {
|
||||
el_ty = vec->type();
|
||||
} else if (auto* mat = el_ty->As<sem::Matrix>()) {
|
||||
el_ty = mat->type();
|
||||
}
|
||||
if (i == 0) {
|
||||
arg_el_ty = el_ty;
|
||||
} else if (arg_el_ty != el_ty) {
|
||||
arg_el_ty = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
arg_behaviors.Remove(sem::Behavior::kNext);
|
||||
|
@ -1273,10 +1298,71 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) {
|
|||
// Resolve the target of the CallExpression to determine whether this is a
|
||||
// function call, cast or type constructor expression.
|
||||
if (expr->target.type) {
|
||||
auto* ty = Type(expr->target.type);
|
||||
if (!ty) {
|
||||
return nullptr;
|
||||
const sem::Type* ty = nullptr;
|
||||
|
||||
auto err_cannot_infer_el_ty = [&](std::string name) {
|
||||
AddError(
|
||||
"cannot infer " + name +
|
||||
" element type, as constructor arguments have different types",
|
||||
expr->source);
|
||||
for (size_t i = 0; i < args.size(); i++) {
|
||||
auto* arg = args[i];
|
||||
AddNote("argument " + std::to_string(i) + " has type " +
|
||||
arg->Type()->FriendlyName(builder_->Symbols()),
|
||||
arg->Declaration()->source);
|
||||
}
|
||||
};
|
||||
|
||||
if (!expr->args.empty()) {
|
||||
// vecN() without explicit element type?
|
||||
// Try to infer element type from args
|
||||
if (auto* vec = expr->target.type->As<ast::Vector>()) {
|
||||
if (!vec->type) {
|
||||
if (!arg_el_ty) {
|
||||
err_cannot_infer_el_ty("vector");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Mark(vec);
|
||||
auto* v = builder_->create<sem::Vector>(
|
||||
arg_el_ty, static_cast<uint32_t>(vec->width));
|
||||
if (!ValidateVector(v, vec->source)) {
|
||||
return nullptr;
|
||||
}
|
||||
builder_->Sem().Add(vec, v);
|
||||
ty = v;
|
||||
}
|
||||
}
|
||||
|
||||
// matNxM() without explicit element type?
|
||||
// Try to infer element type from args
|
||||
if (auto* mat = expr->target.type->As<ast::Matrix>()) {
|
||||
if (!mat->type) {
|
||||
if (!arg_el_ty) {
|
||||
err_cannot_infer_el_ty("matrix");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Mark(mat);
|
||||
auto* column_type =
|
||||
builder_->create<sem::Vector>(arg_el_ty, mat->rows);
|
||||
auto* m = builder_->create<sem::Matrix>(column_type, mat->columns);
|
||||
if (!ValidateMatrix(m, mat->source)) {
|
||||
return nullptr;
|
||||
}
|
||||
builder_->Sem().Add(mat, m);
|
||||
ty = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ty == nullptr) {
|
||||
ty = Type(expr->target.type);
|
||||
if (!ty) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return type_ctor_or_conv(ty);
|
||||
}
|
||||
|
||||
|
@ -1393,16 +1479,16 @@ sem::Call* Resolver::TypeConversion(const ast::CallExpression* expr,
|
|||
auto* call_target = utils::GetOrCreate(
|
||||
type_conversions_, TypeConversionSig{target, source},
|
||||
[&]() -> sem::TypeConversion* {
|
||||
// Now that the argument types have been determined, make sure that they
|
||||
// obey the conversion rules laid out in
|
||||
// Now that the argument types have been determined, make sure that
|
||||
// they obey the conversion rules laid out in
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#conversion-expr.
|
||||
bool ok = true;
|
||||
if (auto* vec_type = target->As<sem::Vector>()) {
|
||||
ok = ValidateVectorConstructorOrCast(expr, vec_type);
|
||||
} else if (auto* mat_type = target->As<sem::Matrix>()) {
|
||||
// Note: Matrix types currently cannot be converted (the element type
|
||||
// must only be f32). We implement this for the day we support other
|
||||
// matrix element types.
|
||||
// Note: Matrix types currently cannot be converted (the element
|
||||
// type must only be f32). We implement this for the day we support
|
||||
// other matrix element types.
|
||||
ok = ValidateMatrixConstructorOrCast(expr, mat_type);
|
||||
} else if (target->is_scalar()) {
|
||||
ok = ValidateScalarConstructorOrCast(expr, target);
|
||||
|
@ -1452,8 +1538,8 @@ sem::Call* Resolver::TypeConstructor(
|
|||
auto* call_target = utils::GetOrCreate(
|
||||
type_ctors_, TypeConstructorSig{ty, arg_tys},
|
||||
[&]() -> sem::TypeConstructor* {
|
||||
// Now that the argument types have been determined, make sure that they
|
||||
// obey the constructor type rules laid out in
|
||||
// Now that the argument types have been determined, make sure that
|
||||
// they obey the constructor type rules laid out in
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#type-constructor-expr.
|
||||
bool ok = true;
|
||||
if (auto* vec_type = ty->As<sem::Vector>()) {
|
||||
|
@ -2359,8 +2445,8 @@ sem::Statement* Resolver::ReturnStatement(const ast::ReturnStatement* stmt) {
|
|||
behaviors.Add(expr->Behaviors() - sem::Behavior::kNext);
|
||||
}
|
||||
|
||||
// Validate after processing the return value expression so that its type is
|
||||
// available for validation.
|
||||
// Validate after processing the return value expression so that its type
|
||||
// is available for validation.
|
||||
return ValidateReturn(stmt);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1853,6 +1853,12 @@ bool Resolver::ValidateMatrixConstructorOrCast(const ast::CallExpression* ctor,
|
|||
return false;
|
||||
}
|
||||
|
||||
std::vector<const sem::Type*> arg_tys;
|
||||
arg_tys.reserve(values.size());
|
||||
for (auto* value : values) {
|
||||
arg_tys.emplace_back(TypeOf(value)->UnwrapRef());
|
||||
}
|
||||
|
||||
auto* elem_type = matrix_ty->type();
|
||||
auto num_elements = matrix_ty->columns() * matrix_ty->rows();
|
||||
|
||||
|
@ -1864,7 +1870,14 @@ bool Resolver::ValidateMatrixConstructorOrCast(const ast::CallExpression* ctor,
|
|||
auto type_name = TypeNameOf(matrix_ty);
|
||||
auto elem_type_name = TypeNameOf(elem_type);
|
||||
std::stringstream ss;
|
||||
ss << "invalid constructor for " + type_name << std::endl << std::endl;
|
||||
ss << "no matching constructor " + type_name << "(";
|
||||
for (size_t i = 0; i < values.size(); i++) {
|
||||
if (i > 0) {
|
||||
ss << ", ";
|
||||
}
|
||||
ss << arg_tys[i]->FriendlyName(builder_->Symbols());
|
||||
}
|
||||
ss << ")" << std::endl << std::endl;
|
||||
ss << "3 candidates available:" << std::endl;
|
||||
ss << " " << type_name << "()" << std::endl;
|
||||
ss << " " << type_name << "(" << elem_type_name << ",...,"
|
||||
|
@ -1893,8 +1906,8 @@ bool Resolver::ValidateMatrixConstructorOrCast(const ast::CallExpression* ctor,
|
|||
return false;
|
||||
}
|
||||
|
||||
for (auto* value : values) {
|
||||
if (TypeOf(value)->UnwrapRef() != expected_arg_type) {
|
||||
for (auto* arg_ty : arg_tys) {
|
||||
if (arg_ty != expected_arg_type) {
|
||||
print_error();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1821,6 +1821,386 @@ TEST_F(ResolverTypeConstructorValidationTest,
|
|||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest, InferVec2ElementTypeFromScalars) {
|
||||
auto* vec2_bool =
|
||||
Construct(create<ast::Vector>(nullptr, 2), Expr(true), Expr(false));
|
||||
auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2), Expr(1), Expr(2));
|
||||
auto* vec2_u32 =
|
||||
Construct(create<ast::Vector>(nullptr, 2), Expr(1u), Expr(2u));
|
||||
auto* vec2_f32 =
|
||||
Construct(create<ast::Vector>(nullptr, 2), Expr(1.0f), Expr(2.0f));
|
||||
WrapInFunction(vec2_bool, vec2_i32, vec2_u32, vec2_f32);
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_TRUE(TypeOf(vec2_bool)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec2_i32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec2_u32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec2_f32)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(vec2_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
|
||||
EXPECT_TRUE(TypeOf(vec2_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
EXPECT_TRUE(TypeOf(vec2_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
|
||||
EXPECT_TRUE(TypeOf(vec2_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(TypeOf(vec2_bool)->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_EQ(TypeOf(vec2_i32)->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_EQ(TypeOf(vec2_u32)->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_EQ(TypeOf(vec2_f32)->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_EQ(TypeOf(vec2_bool), TypeOf(vec2_bool->target.type));
|
||||
EXPECT_EQ(TypeOf(vec2_i32), TypeOf(vec2_i32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec2_u32), TypeOf(vec2_u32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec2_f32), TypeOf(vec2_f32->target.type));
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest, InferVec2ElementTypeFromVec2) {
|
||||
auto* vec2_bool =
|
||||
Construct(create<ast::Vector>(nullptr, 2), vec2<bool>(true, false));
|
||||
auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2), vec2<i32>(1, 2));
|
||||
auto* vec2_u32 =
|
||||
Construct(create<ast::Vector>(nullptr, 2), vec2<u32>(1u, 2u));
|
||||
auto* vec2_f32 =
|
||||
Construct(create<ast::Vector>(nullptr, 2), vec2<f32>(1.0f, 2.0f));
|
||||
WrapInFunction(vec2_bool, vec2_i32, vec2_u32, vec2_f32);
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_TRUE(TypeOf(vec2_bool)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec2_i32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec2_u32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec2_f32)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(vec2_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
|
||||
EXPECT_TRUE(TypeOf(vec2_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
EXPECT_TRUE(TypeOf(vec2_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
|
||||
EXPECT_TRUE(TypeOf(vec2_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(TypeOf(vec2_bool)->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_EQ(TypeOf(vec2_i32)->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_EQ(TypeOf(vec2_u32)->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_EQ(TypeOf(vec2_f32)->As<sem::Vector>()->Width(), 2u);
|
||||
EXPECT_EQ(TypeOf(vec2_bool), TypeOf(vec2_bool->target.type));
|
||||
EXPECT_EQ(TypeOf(vec2_i32), TypeOf(vec2_i32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec2_u32), TypeOf(vec2_u32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec2_f32), TypeOf(vec2_f32->target.type));
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest, InferVec3ElementTypeFromScalars) {
|
||||
auto* vec3_bool = Construct(create<ast::Vector>(nullptr, 3), Expr(true),
|
||||
Expr(false), Expr(true));
|
||||
auto* vec3_i32 =
|
||||
Construct(create<ast::Vector>(nullptr, 3), Expr(1), Expr(2), Expr(3));
|
||||
auto* vec3_u32 =
|
||||
Construct(create<ast::Vector>(nullptr, 3), Expr(1u), Expr(2u), Expr(3u));
|
||||
auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1.0f),
|
||||
Expr(2.0f), Expr(3.0f));
|
||||
WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32);
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_TRUE(TypeOf(vec3_bool)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec3_i32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec3_u32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec3_f32)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(vec3_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
|
||||
EXPECT_TRUE(TypeOf(vec3_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
EXPECT_TRUE(TypeOf(vec3_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
|
||||
EXPECT_TRUE(TypeOf(vec3_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(TypeOf(vec3_bool)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_i32)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_u32)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_f32)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_bool), TypeOf(vec3_bool->target.type));
|
||||
EXPECT_EQ(TypeOf(vec3_i32), TypeOf(vec3_i32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec3_u32), TypeOf(vec3_u32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec3_f32), TypeOf(vec3_f32->target.type));
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest, InferVec3ElementTypeFromVec3) {
|
||||
auto* vec3_bool =
|
||||
Construct(create<ast::Vector>(nullptr, 3), vec3<bool>(true, false, true));
|
||||
auto* vec3_i32 =
|
||||
Construct(create<ast::Vector>(nullptr, 3), vec3<i32>(1, 2, 3));
|
||||
auto* vec3_u32 =
|
||||
Construct(create<ast::Vector>(nullptr, 3), vec3<u32>(1u, 2u, 3u));
|
||||
auto* vec3_f32 =
|
||||
Construct(create<ast::Vector>(nullptr, 3), vec3<f32>(1.0f, 2.0f, 3.0f));
|
||||
WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32);
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_TRUE(TypeOf(vec3_bool)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec3_i32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec3_u32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec3_f32)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(vec3_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
|
||||
EXPECT_TRUE(TypeOf(vec3_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
EXPECT_TRUE(TypeOf(vec3_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
|
||||
EXPECT_TRUE(TypeOf(vec3_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(TypeOf(vec3_bool)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_i32)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_u32)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_f32)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_bool), TypeOf(vec3_bool->target.type));
|
||||
EXPECT_EQ(TypeOf(vec3_i32), TypeOf(vec3_i32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec3_u32), TypeOf(vec3_u32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec3_f32), TypeOf(vec3_f32->target.type));
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
InferVec3ElementTypeFromScalarAndVec2) {
|
||||
auto* vec3_bool = Construct(create<ast::Vector>(nullptr, 3), Expr(true),
|
||||
vec2<bool>(false, true));
|
||||
auto* vec3_i32 =
|
||||
Construct(create<ast::Vector>(nullptr, 3), Expr(1), vec2<i32>(2, 3));
|
||||
auto* vec3_u32 =
|
||||
Construct(create<ast::Vector>(nullptr, 3), Expr(1u), vec2<u32>(2u, 3u));
|
||||
auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1.0f),
|
||||
vec2<f32>(2.0f, 3.0f));
|
||||
WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32);
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_TRUE(TypeOf(vec3_bool)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec3_i32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec3_u32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec3_f32)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(vec3_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
|
||||
EXPECT_TRUE(TypeOf(vec3_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
EXPECT_TRUE(TypeOf(vec3_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
|
||||
EXPECT_TRUE(TypeOf(vec3_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(TypeOf(vec3_bool)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_i32)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_u32)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_f32)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_EQ(TypeOf(vec3_bool), TypeOf(vec3_bool->target.type));
|
||||
EXPECT_EQ(TypeOf(vec3_i32), TypeOf(vec3_i32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec3_u32), TypeOf(vec3_u32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec3_f32), TypeOf(vec3_f32->target.type));
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest, InferVec4ElementTypeFromScalars) {
|
||||
auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4), Expr(true),
|
||||
Expr(false), Expr(true), Expr(false));
|
||||
auto* vec4_i32 = Construct(create<ast::Vector>(nullptr, 4), Expr(1), Expr(2),
|
||||
Expr(3), Expr(4));
|
||||
auto* vec4_u32 = Construct(create<ast::Vector>(nullptr, 4), Expr(1u),
|
||||
Expr(2u), Expr(3u), Expr(4u));
|
||||
auto* vec4_f32 = Construct(create<ast::Vector>(nullptr, 4), Expr(1.0f),
|
||||
Expr(2.0f), Expr(3.0f), Expr(4.0f));
|
||||
WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_TRUE(TypeOf(vec4_bool)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_i32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_u32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_f32)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(vec4_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
|
||||
EXPECT_TRUE(TypeOf(vec4_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
EXPECT_TRUE(TypeOf(vec4_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
|
||||
EXPECT_TRUE(TypeOf(vec4_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(TypeOf(vec4_bool)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_i32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_u32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_f32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_bool), TypeOf(vec4_bool->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_i32), TypeOf(vec4_i32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_u32), TypeOf(vec4_u32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_f32), TypeOf(vec4_f32->target.type));
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest, InferVec4ElementTypeFromVec4) {
|
||||
auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4),
|
||||
vec4<bool>(true, false, true, false));
|
||||
auto* vec4_i32 =
|
||||
Construct(create<ast::Vector>(nullptr, 4), vec4<i32>(1, 2, 3, 4));
|
||||
auto* vec4_u32 =
|
||||
Construct(create<ast::Vector>(nullptr, 4), vec4<u32>(1u, 2u, 3u, 4u));
|
||||
auto* vec4_f32 = Construct(create<ast::Vector>(nullptr, 4),
|
||||
vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f));
|
||||
WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_TRUE(TypeOf(vec4_bool)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_i32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_u32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_f32)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(vec4_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
|
||||
EXPECT_TRUE(TypeOf(vec4_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
EXPECT_TRUE(TypeOf(vec4_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
|
||||
EXPECT_TRUE(TypeOf(vec4_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(TypeOf(vec4_bool)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_i32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_u32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_f32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_bool), TypeOf(vec4_bool->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_i32), TypeOf(vec4_i32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_u32), TypeOf(vec4_u32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_f32), TypeOf(vec4_f32->target.type));
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
InferVec4ElementTypeFromScalarAndVec3) {
|
||||
auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4), Expr(true),
|
||||
vec3<bool>(false, true, false));
|
||||
auto* vec4_i32 =
|
||||
Construct(create<ast::Vector>(nullptr, 4), Expr(1), vec3<i32>(2, 3, 4));
|
||||
auto* vec4_u32 = Construct(create<ast::Vector>(nullptr, 4), Expr(1u),
|
||||
vec3<u32>(2u, 3u, 4u));
|
||||
auto* vec4_f32 = Construct(create<ast::Vector>(nullptr, 4), Expr(1.0f),
|
||||
vec3<f32>(2.0f, 3.0f, 4.0f));
|
||||
WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_TRUE(TypeOf(vec4_bool)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_i32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_u32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_f32)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(vec4_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
|
||||
EXPECT_TRUE(TypeOf(vec4_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
EXPECT_TRUE(TypeOf(vec4_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
|
||||
EXPECT_TRUE(TypeOf(vec4_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(TypeOf(vec4_bool)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_i32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_u32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_f32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_bool), TypeOf(vec4_bool->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_i32), TypeOf(vec4_i32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_u32), TypeOf(vec4_u32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_f32), TypeOf(vec4_f32->target.type));
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
InferVec4ElementTypeFromVec2AndVec2) {
|
||||
auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4),
|
||||
vec2<bool>(true, false), vec2<bool>(true, false));
|
||||
auto* vec4_i32 = Construct(create<ast::Vector>(nullptr, 4), vec2<i32>(1, 2),
|
||||
vec2<i32>(3, 4));
|
||||
auto* vec4_u32 = Construct(create<ast::Vector>(nullptr, 4), vec2<u32>(1u, 2u),
|
||||
vec2<u32>(3u, 4u));
|
||||
auto* vec4_f32 = Construct(create<ast::Vector>(nullptr, 4),
|
||||
vec2<f32>(1.0f, 2.0f), vec2<f32>(3.0f, 4.0f));
|
||||
WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_TRUE(TypeOf(vec4_bool)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_i32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_u32)->Is<sem::Vector>());
|
||||
ASSERT_TRUE(TypeOf(vec4_f32)->Is<sem::Vector>());
|
||||
EXPECT_TRUE(TypeOf(vec4_bool)->As<sem::Vector>()->type()->Is<sem::Bool>());
|
||||
EXPECT_TRUE(TypeOf(vec4_i32)->As<sem::Vector>()->type()->Is<sem::I32>());
|
||||
EXPECT_TRUE(TypeOf(vec4_u32)->As<sem::Vector>()->type()->Is<sem::U32>());
|
||||
EXPECT_TRUE(TypeOf(vec4_f32)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
EXPECT_EQ(TypeOf(vec4_bool)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_i32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_u32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_f32)->As<sem::Vector>()->Width(), 4u);
|
||||
EXPECT_EQ(TypeOf(vec4_bool), TypeOf(vec4_bool->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_i32), TypeOf(vec4_i32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_u32), TypeOf(vec4_u32->target.type));
|
||||
EXPECT_EQ(TypeOf(vec4_f32), TypeOf(vec4_f32->target.type));
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
CannotInferVectorElementTypeWithoutArgs) {
|
||||
WrapInFunction(Construct(create<ast::Vector>(Source{{12, 34}}, nullptr, 3)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
CannotInferVec2ElementTypeFromScalarsMismatch) {
|
||||
WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 2),
|
||||
Expr(Source{{1, 2}}, 1), //
|
||||
Expr(Source{{1, 3}}, 2u)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
|
||||
1:2 note: argument 0 has type i32
|
||||
1:3 note: argument 1 has type u32)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
CannotInferVec3ElementTypeFromScalarsMismatch) {
|
||||
WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 3),
|
||||
Expr(Source{{1, 2}}, 1), //
|
||||
Expr(Source{{1, 3}}, 2u), //
|
||||
Expr(Source{{1, 4}}, 3)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
|
||||
1:2 note: argument 0 has type i32
|
||||
1:3 note: argument 1 has type u32
|
||||
1:4 note: argument 2 has type i32)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
CannotInferVec3ElementTypeFromScalarAndVec2Mismatch) {
|
||||
WrapInFunction(
|
||||
Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 3),
|
||||
Expr(Source{{1, 2}}, 1), //
|
||||
Construct(Source{{1, 3}}, ty.vec2<f32>(), 2.0f, 3.0f)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
|
||||
1:2 note: argument 0 has type i32
|
||||
1:3 note: argument 1 has type vec2<f32>)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
CannotInferVec4ElementTypeFromScalarsMismatch) {
|
||||
WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4),
|
||||
Expr(Source{{1, 2}}, 1), //
|
||||
Expr(Source{{1, 3}}, 2), //
|
||||
Expr(Source{{1, 4}}, 3.0f), //
|
||||
Expr(Source{{1, 5}}, 4)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
|
||||
1:2 note: argument 0 has type i32
|
||||
1:3 note: argument 1 has type i32
|
||||
1:4 note: argument 2 has type f32
|
||||
1:5 note: argument 3 has type i32)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
CannotInferVec4ElementTypeFromScalarAndVec3Mismatch) {
|
||||
WrapInFunction(
|
||||
Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4),
|
||||
Expr(Source{{1, 2}}, 1), //
|
||||
Construct(Source{{1, 3}}, ty.vec3<u32>(), 2u, 3u, 4u)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
|
||||
1:2 note: argument 0 has type i32
|
||||
1:3 note: argument 1 has type vec3<u32>)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
CannotInferVec4ElementTypeFromVec2AndVec2Mismatch) {
|
||||
WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4),
|
||||
Construct(Source{{1, 2}}, ty.vec2<i32>(), 3, 4), //
|
||||
Construct(Source{{1, 3}}, ty.vec2<u32>(), 3u, 4u)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(1:1 error: cannot infer vector element type, as constructor arguments have different types
|
||||
1:2 note: argument 0 has type vec2<i32>
|
||||
1:3 note: argument 1 has type vec2<u32>)");
|
||||
}
|
||||
|
||||
} // namespace VectorConstructor
|
||||
|
||||
namespace MatrixConstructor {
|
||||
|
@ -1841,10 +2221,15 @@ TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooFewArguments) {
|
|||
|
||||
const auto param = GetParam();
|
||||
|
||||
std::stringstream args_tys;
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns - 1; i++) {
|
||||
auto* vec_type = ty.vec<f32>(param.rows);
|
||||
args.push_back(Construct(Source{{12, i}}, vec_type));
|
||||
if (i > 1) {
|
||||
args_tys << ", ";
|
||||
}
|
||||
args_tys << "vec" << param.rows << "<f32>";
|
||||
}
|
||||
|
||||
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
|
||||
|
@ -1852,9 +2237,9 @@ TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooFewArguments) {
|
|||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("12:1 error: invalid constructor for " +
|
||||
MatrixStr(param) + "\n\n3 candidates available:"));
|
||||
EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " +
|
||||
MatrixStr(param) + "(" + args_tys.str() +
|
||||
")\n\n3 candidates available:"));
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_TooFewArguments) {
|
||||
|
@ -1862,9 +2247,14 @@ TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_TooFewArguments) {
|
|||
|
||||
const auto param = GetParam();
|
||||
|
||||
std::stringstream args_tys;
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns * param.rows - 1; i++) {
|
||||
args.push_back(Construct(Source{{12, i}}, ty.f32()));
|
||||
if (i > 1) {
|
||||
args_tys << ", ";
|
||||
}
|
||||
args_tys << "f32";
|
||||
}
|
||||
|
||||
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
|
||||
|
@ -1872,9 +2262,9 @@ TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_TooFewArguments) {
|
|||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("12:1 error: invalid constructor for " +
|
||||
MatrixStr(param) + "\n\n3 candidates available:"));
|
||||
EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " +
|
||||
MatrixStr(param) + "(" + args_tys.str() +
|
||||
")\n\n3 candidates available:"));
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooManyArguments) {
|
||||
|
@ -1882,10 +2272,15 @@ TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooManyArguments) {
|
|||
|
||||
const auto param = GetParam();
|
||||
|
||||
std::stringstream args_tys;
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns + 1; i++) {
|
||||
auto* vec_type = ty.vec<f32>(param.rows);
|
||||
args.push_back(Construct(Source{{12, i}}, vec_type));
|
||||
if (i > 1) {
|
||||
args_tys << ", ";
|
||||
}
|
||||
args_tys << "vec" << param.rows << "<f32>";
|
||||
}
|
||||
|
||||
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
|
||||
|
@ -1893,9 +2288,9 @@ TEST_P(MatrixConstructorTest, Expr_ColumnConstructor_Error_TooManyArguments) {
|
|||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("12:1 error: invalid constructor for " +
|
||||
MatrixStr(param) + "\n\n3 candidates available:"));
|
||||
EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " +
|
||||
MatrixStr(param) + "(" + args_tys.str() +
|
||||
")\n\n3 candidates available:"));
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_TooManyArguments) {
|
||||
|
@ -1903,9 +2298,14 @@ TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_TooManyArguments) {
|
|||
|
||||
const auto param = GetParam();
|
||||
|
||||
std::stringstream args_tys;
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns * param.rows + 1; i++) {
|
||||
args.push_back(Construct(Source{{12, i}}, ty.f32()));
|
||||
if (i > 1) {
|
||||
args_tys << ", ";
|
||||
}
|
||||
args_tys << "f32";
|
||||
}
|
||||
|
||||
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
|
||||
|
@ -1913,9 +2313,9 @@ TEST_P(MatrixConstructorTest, Expr_ElementConstructor_Error_TooManyArguments) {
|
|||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("12:1 error: invalid constructor for " +
|
||||
MatrixStr(param) + "\n\n3 candidates available:"));
|
||||
EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " +
|
||||
MatrixStr(param) + "(" + args_tys.str() +
|
||||
")\n\n3 candidates available:"));
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest,
|
||||
|
@ -1924,10 +2324,15 @@ TEST_P(MatrixConstructorTest,
|
|||
|
||||
const auto param = GetParam();
|
||||
|
||||
std::stringstream args_tys;
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns; i++) {
|
||||
auto* vec_type = ty.vec<u32>(param.rows);
|
||||
args.push_back(Construct(Source{{12, i}}, vec_type));
|
||||
if (i > 1) {
|
||||
args_tys << ", ";
|
||||
}
|
||||
args_tys << "vec" << param.rows << "<u32>";
|
||||
}
|
||||
|
||||
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
|
||||
|
@ -1935,9 +2340,9 @@ TEST_P(MatrixConstructorTest,
|
|||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("12:1 error: invalid constructor for " +
|
||||
MatrixStr(param) + "\n\n3 candidates available:"));
|
||||
EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " +
|
||||
MatrixStr(param) + "(" + args_tys.str() +
|
||||
")\n\n3 candidates available:"));
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest,
|
||||
|
@ -1946,9 +2351,14 @@ TEST_P(MatrixConstructorTest,
|
|||
|
||||
const auto param = GetParam();
|
||||
|
||||
std::stringstream args_tys;
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns; i++) {
|
||||
args.push_back(Expr(Source{{12, i}}, 1u));
|
||||
if (i > 1) {
|
||||
args_tys << ", ";
|
||||
}
|
||||
args_tys << "u32";
|
||||
}
|
||||
|
||||
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
|
||||
|
@ -1956,9 +2366,9 @@ TEST_P(MatrixConstructorTest,
|
|||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("12:1 error: invalid constructor for " +
|
||||
MatrixStr(param) + "\n\n3 candidates available:"));
|
||||
EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " +
|
||||
MatrixStr(param) + "(" + args_tys.str() +
|
||||
")\n\n3 candidates available:"));
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest,
|
||||
|
@ -1972,23 +2382,29 @@ TEST_P(MatrixConstructorTest,
|
|||
return;
|
||||
}
|
||||
|
||||
std::stringstream args_tys;
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns - 1; i++) {
|
||||
auto* valid_vec_type = ty.vec<f32>(param.rows);
|
||||
args.push_back(Construct(Source{{12, i}}, valid_vec_type));
|
||||
if (i > 1) {
|
||||
args_tys << ", ";
|
||||
}
|
||||
args_tys << "vec" << param.rows << "<f32>";
|
||||
}
|
||||
const size_t kInvalidLoc = 2 * (param.columns - 1);
|
||||
auto* invalid_vec_type = ty.vec<f32>(param.rows - 1);
|
||||
args.push_back(Construct(Source{{12, kInvalidLoc}}, invalid_vec_type));
|
||||
args_tys << ", vec" << (param.rows - 1) << "<f32>";
|
||||
|
||||
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
|
||||
auto* tc = Construct(Source{}, matrix_type, std::move(args));
|
||||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("12:1 error: invalid constructor for " +
|
||||
MatrixStr(param) + "\n\n3 candidates available:"));
|
||||
EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " +
|
||||
MatrixStr(param) + "(" + args_tys.str() +
|
||||
")\n\n3 candidates available:"));
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest,
|
||||
|
@ -1997,28 +2413,34 @@ TEST_P(MatrixConstructorTest,
|
|||
|
||||
const auto param = GetParam();
|
||||
|
||||
// Skip the test if parameters would have resuled in an invalid vec5 type.
|
||||
// Skip the test if parameters would have resulted in an invalid vec5 type.
|
||||
if (param.rows == 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream args_tys;
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns - 1; i++) {
|
||||
auto* valid_vec_type = ty.vec<f32>(param.rows);
|
||||
args.push_back(Construct(Source{{12, i}}, valid_vec_type));
|
||||
if (i > 1) {
|
||||
args_tys << ", ";
|
||||
}
|
||||
args_tys << "vec" << param.rows << "<f32>";
|
||||
}
|
||||
const size_t kInvalidLoc = 2 * (param.columns - 1);
|
||||
auto* invalid_vec_type = ty.vec<f32>(param.rows + 1);
|
||||
args.push_back(Construct(Source{{12, kInvalidLoc}}, invalid_vec_type));
|
||||
args_tys << ", vec" << (param.rows + 1) << "<f32>";
|
||||
|
||||
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
|
||||
auto* tc = Construct(Source{}, matrix_type, std::move(args));
|
||||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("12:1 error: invalid constructor for " +
|
||||
MatrixStr(param) + "\n\n3 candidates available:"));
|
||||
EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " +
|
||||
MatrixStr(param) + "(" + args_tys.str() +
|
||||
")\n\n3 candidates available:"));
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest, Expr_Constructor_ZeroValue_Success) {
|
||||
|
@ -2073,10 +2495,15 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Error) {
|
|||
const auto param = GetParam();
|
||||
auto* f32_alias = Alias("Float32", ty.f32());
|
||||
|
||||
std::stringstream args_tys;
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns; i++) {
|
||||
auto* vec_type = ty.vec(ty.u32(), param.rows);
|
||||
args.push_back(Construct(Source{{12, i}}, vec_type));
|
||||
if (i > 1) {
|
||||
args_tys << ", ";
|
||||
}
|
||||
args_tys << "vec" << param.rows << "<u32>";
|
||||
}
|
||||
|
||||
auto* matrix_type = ty.mat(ty.Of(f32_alias), param.columns, param.rows);
|
||||
|
@ -2084,9 +2511,9 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Error) {
|
|||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("12:1 error: invalid constructor for " +
|
||||
MatrixStr(param) + "\n\n3 candidates available:"));
|
||||
EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " +
|
||||
MatrixStr(param) + "(" + args_tys.str() +
|
||||
")\n\n3 candidates available:"));
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Success) {
|
||||
|
@ -2116,8 +2543,9 @@ TEST_F(ResolverTypeConstructorValidationTest,
|
|||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(),
|
||||
R"(12:34 error: invalid constructor for mat2x2<f32>
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(12:34 error: no matching constructor mat2x2<f32>(vec2<u32>, vec2<f32>)
|
||||
|
||||
3 candidates available:
|
||||
mat2x2<f32>()
|
||||
|
@ -2148,19 +2576,24 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Error) {
|
|||
auto* matrix_type = ty.mat<f32>(param.columns, param.rows);
|
||||
auto* f32_alias = Alias("UnsignedInt", ty.u32());
|
||||
|
||||
std::stringstream args_tys;
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns; i++) {
|
||||
auto* vec_type = ty.vec(ty.Of(f32_alias), param.rows);
|
||||
args.push_back(Construct(Source{{12, i}}, vec_type));
|
||||
if (i > 1) {
|
||||
args_tys << ", ";
|
||||
}
|
||||
args_tys << "vec" << param.rows << "<u32>";
|
||||
}
|
||||
|
||||
auto* tc = Construct(Source{}, matrix_type, std::move(args));
|
||||
WrapInFunction(tc);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("12:1 error: invalid constructor for " +
|
||||
MatrixStr(param) + "\n\n3 candidates available:"));
|
||||
EXPECT_THAT(r()->error(), HasSubstr("12:1 error: no matching constructor " +
|
||||
MatrixStr(param) + "(" + args_tys.str() +
|
||||
")\n\n3 candidates available:"));
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest,
|
||||
|
@ -2181,6 +2614,91 @@ TEST_P(MatrixConstructorTest,
|
|||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest, InferElementTypeFromVectors) {
|
||||
const auto param = GetParam();
|
||||
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 1; i <= param.columns; i++) {
|
||||
args.push_back(Construct(ty.vec<f32>(param.rows)));
|
||||
}
|
||||
|
||||
auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
|
||||
auto* tc = Construct(Source{}, matrix_type, std::move(args));
|
||||
WrapInFunction(tc);
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest, InferElementTypeFromScalars) {
|
||||
const auto param = GetParam();
|
||||
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 0; i < param.rows * param.columns; i++) {
|
||||
args.push_back(Expr(static_cast<f32>(i)));
|
||||
}
|
||||
|
||||
auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
|
||||
WrapInFunction(Construct(Source{{12, 34}}, matrix_type, std::move(args)));
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest, CannotInferElementTypeFromVectors_Mismatch) {
|
||||
const auto param = GetParam();
|
||||
|
||||
std::stringstream err;
|
||||
err << "12:34 error: cannot infer matrix element type, as constructor "
|
||||
"arguments have different types";
|
||||
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 0; i < param.columns; i++) {
|
||||
err << "\n";
|
||||
auto src = Source{{1, 10 + i}};
|
||||
if (i == 1) {
|
||||
// Odd one out
|
||||
args.push_back(Construct(src, ty.vec<i32>(param.rows)));
|
||||
err << src << " note: argument " << i << " has type vec" << param.rows
|
||||
<< "<i32>";
|
||||
} else {
|
||||
args.push_back(Construct(src, ty.vec<f32>(param.rows)));
|
||||
err << src << " note: argument " << i << " has type vec" << param.rows
|
||||
<< "<f32>";
|
||||
}
|
||||
}
|
||||
|
||||
auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
|
||||
WrapInFunction(Construct(Source{{12, 34}}, matrix_type, std::move(args)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(), err.str());
|
||||
}
|
||||
|
||||
TEST_P(MatrixConstructorTest, CannotInferElementTypeFromScalars_Mismatch) {
|
||||
const auto param = GetParam();
|
||||
|
||||
std::stringstream err;
|
||||
err << "12:34 error: cannot infer matrix element type, as constructor "
|
||||
"arguments have different types";
|
||||
ast::ExpressionList args;
|
||||
for (uint32_t i = 0; i < param.rows * param.columns; i++) {
|
||||
err << "\n";
|
||||
auto src = Source{{1, 10 + i}};
|
||||
if (i == 3) {
|
||||
args.push_back(Expr(src, static_cast<i32>(i))); // The odd one out
|
||||
err << src << " note: argument " << i << " has type i32";
|
||||
} else {
|
||||
args.push_back(Expr(src, static_cast<f32>(i)));
|
||||
err << src << " note: argument " << i << " has type f32";
|
||||
}
|
||||
}
|
||||
|
||||
auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
|
||||
WrapInFunction(Construct(Source{{12, 34}}, matrix_type, std::move(args)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_THAT(r()->error(), err.str());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ResolverTypeConstructorValidationTest,
|
||||
MatrixConstructorTest,
|
||||
testing::Values(MatrixDimensions{2, 2},
|
||||
|
|
|
@ -416,6 +416,29 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayInFunction_Fail) {
|
|||
"a struct");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, Struct_Member_VectorNoType) {
|
||||
// struct S {
|
||||
// a: vec3;
|
||||
// };
|
||||
|
||||
Structure("S",
|
||||
{Member("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3))});
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, Struct_Member_MatrixNoType) {
|
||||
// struct S {
|
||||
// a: mat3x3;
|
||||
// };
|
||||
Structure(
|
||||
"S", {Member("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3, 3))});
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, Struct_TooBig) {
|
||||
// struct Foo {
|
||||
// a: array<f32, 0x20000000>;
|
||||
|
@ -795,9 +818,9 @@ TEST_P(StorageTextureDimensionTest, All) {
|
|||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
} else {
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
"12:34 error: cube dimensions for storage textures are not supported");
|
||||
EXPECT_EQ(r()->error(),
|
||||
"12:34 error: cube dimensions for storage textures are not "
|
||||
"supported");
|
||||
}
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
|
||||
|
@ -1064,9 +1087,9 @@ TEST_P(InvalidVectorElementTypes, InvalidElementType) {
|
|||
Global("a", ty.vec(Source{{12, 34}}, params.elem_ty(*this), params.width),
|
||||
ast::StorageClass::kPrivate);
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
"12:34 error: vector element type must be 'bool', 'f32', 'i32' or 'u32'");
|
||||
EXPECT_EQ(r()->error(),
|
||||
"12:34 error: vector element type must be 'bool', 'f32', 'i32' "
|
||||
"or 'u32'");
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
|
||||
InvalidVectorElementTypes,
|
||||
|
|
|
@ -307,6 +307,42 @@ TEST_F(ResolverVarLetValidationTest, InvalidStorageClassForInitializer) {
|
|||
"storage classes 'private' and 'function'");
|
||||
}
|
||||
|
||||
TEST_F(ResolverVarLetValidationTest, VectorLetNoType) {
|
||||
// let a : mat3x3 = mat3x3<f32>();
|
||||
WrapInFunction(Const("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3),
|
||||
vec3<f32>()));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverVarLetValidationTest, VectorVarNoType) {
|
||||
// var a : mat3x3;
|
||||
WrapInFunction(Var("a", create<ast::Vector>(Source{{12, 34}}, nullptr, 3)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: missing vector element type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverVarLetValidationTest, MatrixLetNoType) {
|
||||
// let a : mat3x3 = mat3x3<f32>();
|
||||
WrapInFunction(Const("a",
|
||||
create<ast::Matrix>(Source{{12, 34}}, nullptr, 3, 3),
|
||||
mat3x3<f32>()));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverVarLetValidationTest, MatrixVarNoType) {
|
||||
// var a : mat3x3;
|
||||
WrapInFunction(
|
||||
Var("a", create<ast::Matrix>(Source{{12, 34}}, nullptr, 3, 3)));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace resolver
|
||||
} // namespace tint
|
||||
|
|
|
@ -393,11 +393,14 @@ bool GeneratorImpl::EmitType(std::ostream& out, const ast::Type* ty) {
|
|||
} else if (ty->Is<ast::I32>()) {
|
||||
out << "i32";
|
||||
} else if (auto* mat = ty->As<ast::Matrix>()) {
|
||||
out << "mat" << mat->columns << "x" << mat->rows << "<";
|
||||
if (!EmitType(out, mat->type)) {
|
||||
return false;
|
||||
out << "mat" << mat->columns << "x" << mat->rows;
|
||||
if (auto* el_ty = mat->type) {
|
||||
out << "<";
|
||||
if (!EmitType(out, el_ty)) {
|
||||
return false;
|
||||
}
|
||||
out << ">";
|
||||
}
|
||||
out << ">";
|
||||
} else if (auto* ptr = ty->As<ast::Pointer>()) {
|
||||
out << "ptr<" << ptr->storage_class << ", ";
|
||||
if (!EmitType(out, ptr->type)) {
|
||||
|
@ -493,11 +496,14 @@ bool GeneratorImpl::EmitType(std::ostream& out, const ast::Type* ty) {
|
|||
} else if (ty->Is<ast::U32>()) {
|
||||
out << "u32";
|
||||
} else if (auto* vec = ty->As<ast::Vector>()) {
|
||||
out << "vec" << vec->width << "<";
|
||||
if (!EmitType(out, vec->type)) {
|
||||
return false;
|
||||
out << "vec" << vec->width;
|
||||
if (auto* el_ty = vec->type) {
|
||||
out << "<";
|
||||
if (!EmitType(out, el_ty)) {
|
||||
return false;
|
||||
}
|
||||
out << ">";
|
||||
}
|
||||
out << ">";
|
||||
} else if (ty->Is<ast::Void>()) {
|
||||
out << "void";
|
||||
} else if (auto* tn = ty->As<ast::TypeName>()) {
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
let m = mat2x2(0.0, 1.0,
|
||||
2.0, 3.0);
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float2x2 m = float2x2(0.0f, 1.0f, 2.0f, 3.0f);
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float2x2 m = float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
|
|
@ -0,0 +1,27 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 15
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%mat2v2float = OpTypeMatrix %v2float 2
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%6 = OpConstantComposite %v2float %float_0 %float_1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%9 = OpConstantComposite %v2float %float_2 %float_3
|
||||
%m = OpConstantComposite %mat2v2float %6 %9
|
||||
%void = OpTypeVoid
|
||||
%11 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %11
|
||||
%14 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat2x2(0.0, 1.0, 2.0, 3.0);
|
|
@ -0,0 +1,2 @@
|
|||
let m = mat2x2(vec2<f32>(0.0, 1.0),
|
||||
vec2<f32>(2.0, 3.0));
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float2x2 m = float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float2x2 m = float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
|
|
@ -0,0 +1,27 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 15
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%mat2v2float = OpTypeMatrix %v2float 2
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%6 = OpConstantComposite %v2float %float_0 %float_1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%9 = OpConstantComposite %v2float %float_2 %float_3
|
||||
%m = OpConstantComposite %mat2v2float %6 %9
|
||||
%void = OpTypeVoid
|
||||
%11 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %11
|
||||
%14 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat2x2(vec2<f32>(0.0, 1.0), vec2<f32>(2.0, 3.0));
|
|
@ -0,0 +1,2 @@
|
|||
let m = mat2x3(0.0, 1.0, 2.0,
|
||||
3.0, 4.0, 5.0);
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float2x3 m = float2x3(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f);
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float2x3 m = float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
|
|
@ -0,0 +1,29 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 17
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v3float = OpTypeVector %float 3
|
||||
%mat2v3float = OpTypeMatrix %v3float 2
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
|
||||
%float_3 = OpConstant %float 3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%11 = OpConstantComposite %v3float %float_3 %float_4 %float_5
|
||||
%m = OpConstantComposite %mat2v3float %7 %11
|
||||
%void = OpTypeVoid
|
||||
%13 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %13
|
||||
%16 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat2x3(0.0, 1.0, 2.0, 3.0, 4.0, 5.0);
|
|
@ -0,0 +1,2 @@
|
|||
let m = mat2x3(vec3<f32>(0.0, 1.0, 2.0),
|
||||
vec3<f32>(3.0, 4.0, 5.0));
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float2x3 m = float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float2x3 m = float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
|
|
@ -0,0 +1,29 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 17
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v3float = OpTypeVector %float 3
|
||||
%mat2v3float = OpTypeMatrix %v3float 2
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
|
||||
%float_3 = OpConstant %float 3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%11 = OpConstantComposite %v3float %float_3 %float_4 %float_5
|
||||
%m = OpConstantComposite %mat2v3float %7 %11
|
||||
%void = OpTypeVoid
|
||||
%13 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %13
|
||||
%16 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat2x3(vec3<f32>(0.0, 1.0, 2.0), vec3<f32>(3.0, 4.0, 5.0));
|
|
@ -0,0 +1,2 @@
|
|||
let m = mat2x4(0.0, 1.0, 2.0, 3.0,
|
||||
4.0, 5.0, 6.0, 7.0);
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float2x4 m = float2x4(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f);
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float2x4 m = float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
|
|
@ -0,0 +1,31 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 19
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%mat2v4float = OpTypeMatrix %v4float 2
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%13 = OpConstantComposite %v4float %float_4 %float_5 %float_6 %float_7
|
||||
%m = OpConstantComposite %mat2v4float %8 %13
|
||||
%void = OpTypeVoid
|
||||
%15 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %15
|
||||
%18 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat2x4(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0);
|
|
@ -0,0 +1,2 @@
|
|||
let m = mat2x4(vec4<f32>(0.0, 1.0, 2.0, 3.0),
|
||||
vec4<f32>(4.0, 5.0, 6.0, 7.0));
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float2x4 m = float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float2x4 m = float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
|
|
@ -0,0 +1,31 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 19
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%mat2v4float = OpTypeMatrix %v4float 2
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%13 = OpConstantComposite %v4float %float_4 %float_5 %float_6 %float_7
|
||||
%m = OpConstantComposite %mat2v4float %8 %13
|
||||
%void = OpTypeVoid
|
||||
%15 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %15
|
||||
%18 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat2x4(vec4<f32>(0.0, 1.0, 2.0, 3.0), vec4<f32>(4.0, 5.0, 6.0, 7.0));
|
|
@ -0,0 +1,3 @@
|
|||
let m = mat3x2(0.0, 1.0,
|
||||
2.0, 3.0,
|
||||
4.0, 5.0);
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float3x2 m = float3x2(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f);
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float3x2 m = float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
|
|
@ -0,0 +1,30 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 18
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%mat3v2float = OpTypeMatrix %v2float 3
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%6 = OpConstantComposite %v2float %float_0 %float_1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%9 = OpConstantComposite %v2float %float_2 %float_3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%12 = OpConstantComposite %v2float %float_4 %float_5
|
||||
%m = OpConstantComposite %mat3v2float %6 %9 %12
|
||||
%void = OpTypeVoid
|
||||
%14 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %14
|
||||
%17 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat3x2(0.0, 1.0, 2.0, 3.0, 4.0, 5.0);
|
|
@ -0,0 +1,3 @@
|
|||
let m = mat3x2(vec2<f32>(0.0, 1.0),
|
||||
vec2<f32>(2.0, 3.0),
|
||||
vec2<f32>(4.0, 5.0));
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float3x2 m = float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float3x2 m = float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
|
|
@ -0,0 +1,30 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 18
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%mat3v2float = OpTypeMatrix %v2float 3
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%6 = OpConstantComposite %v2float %float_0 %float_1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%9 = OpConstantComposite %v2float %float_2 %float_3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%12 = OpConstantComposite %v2float %float_4 %float_5
|
||||
%m = OpConstantComposite %mat3v2float %6 %9 %12
|
||||
%void = OpTypeVoid
|
||||
%14 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %14
|
||||
%17 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat3x2(vec2<f32>(0.0, 1.0), vec2<f32>(2.0, 3.0), vec2<f32>(4.0, 5.0));
|
|
@ -0,0 +1,3 @@
|
|||
let m = mat3x3(0.0, 1.0, 2.0,
|
||||
3.0, 4.0, 5.0,
|
||||
6.0, 7.0, 8.0);
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float3x3 m = float3x3(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f);
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float3x3 m = float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
|
|
@ -0,0 +1,33 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 21
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v3float = OpTypeVector %float 3
|
||||
%mat3v3float = OpTypeMatrix %v3float 3
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
|
||||
%float_3 = OpConstant %float 3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%11 = OpConstantComposite %v3float %float_3 %float_4 %float_5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%float_8 = OpConstant %float 8
|
||||
%15 = OpConstantComposite %v3float %float_6 %float_7 %float_8
|
||||
%m = OpConstantComposite %mat3v3float %7 %11 %15
|
||||
%void = OpTypeVoid
|
||||
%17 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %17
|
||||
%20 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat3x3(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);
|
|
@ -0,0 +1,3 @@
|
|||
let m = mat3x3(vec3<f32>(0.0, 1.0, 2.0),
|
||||
vec3<f32>(3.0, 4.0, 5.0),
|
||||
vec3<f32>(6.0, 7.0, 8.0));
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float3x3 m = float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float3x3 m = float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
|
|
@ -0,0 +1,33 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 21
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v3float = OpTypeVector %float 3
|
||||
%mat3v3float = OpTypeMatrix %v3float 3
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
|
||||
%float_3 = OpConstant %float 3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%11 = OpConstantComposite %v3float %float_3 %float_4 %float_5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%float_8 = OpConstant %float 8
|
||||
%15 = OpConstantComposite %v3float %float_6 %float_7 %float_8
|
||||
%m = OpConstantComposite %mat3v3float %7 %11 %15
|
||||
%void = OpTypeVoid
|
||||
%17 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %17
|
||||
%20 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat3x3(vec3<f32>(0.0, 1.0, 2.0), vec3<f32>(3.0, 4.0, 5.0), vec3<f32>(6.0, 7.0, 8.0));
|
|
@ -0,0 +1,3 @@
|
|||
let m = mat3x4(0.0, 1.0, 2.0, 3.0,
|
||||
4.0, 5.0, 6.0, 7.0,
|
||||
8.0, 9.0, 10.0, 11.0);
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float3x4 m = float3x4(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f);
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float3x4 m = float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
|
|
@ -0,0 +1,36 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 24
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%mat3v4float = OpTypeMatrix %v4float 3
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%13 = OpConstantComposite %v4float %float_4 %float_5 %float_6 %float_7
|
||||
%float_8 = OpConstant %float 8
|
||||
%float_9 = OpConstant %float 9
|
||||
%float_10 = OpConstant %float 10
|
||||
%float_11 = OpConstant %float 11
|
||||
%18 = OpConstantComposite %v4float %float_8 %float_9 %float_10 %float_11
|
||||
%m = OpConstantComposite %mat3v4float %8 %13 %18
|
||||
%void = OpTypeVoid
|
||||
%20 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %20
|
||||
%23 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat3x4(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0);
|
|
@ -0,0 +1,3 @@
|
|||
let m = mat3x4(vec4<f32>(0.0, 1.0, 2.0, 3.0),
|
||||
vec4<f32>(4.0, 5.0, 6.0, 7.0),
|
||||
vec4<f32>(8.0, 9.0, 10.0, 11.0));
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float3x4 m = float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float3x4 m = float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
|
|
@ -0,0 +1,36 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 24
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%mat3v4float = OpTypeMatrix %v4float 3
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%13 = OpConstantComposite %v4float %float_4 %float_5 %float_6 %float_7
|
||||
%float_8 = OpConstant %float 8
|
||||
%float_9 = OpConstant %float 9
|
||||
%float_10 = OpConstant %float 10
|
||||
%float_11 = OpConstant %float 11
|
||||
%18 = OpConstantComposite %v4float %float_8 %float_9 %float_10 %float_11
|
||||
%m = OpConstantComposite %mat3v4float %8 %13 %18
|
||||
%void = OpTypeVoid
|
||||
%20 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %20
|
||||
%23 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat3x4(vec4<f32>(0.0, 1.0, 2.0, 3.0), vec4<f32>(4.0, 5.0, 6.0, 7.0), vec4<f32>(8.0, 9.0, 10.0, 11.0));
|
|
@ -0,0 +1,4 @@
|
|||
let m = mat4x2(0.0, 1.0,
|
||||
2.0, 3.0,
|
||||
4.0, 5.0,
|
||||
6.0, 7.0);
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float4x2 m = float4x2(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f);
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float4x2 m = float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
|
|
@ -0,0 +1,33 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 21
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%mat4v2float = OpTypeMatrix %v2float 4
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%6 = OpConstantComposite %v2float %float_0 %float_1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%9 = OpConstantComposite %v2float %float_2 %float_3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%12 = OpConstantComposite %v2float %float_4 %float_5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%15 = OpConstantComposite %v2float %float_6 %float_7
|
||||
%m = OpConstantComposite %mat4v2float %6 %9 %12 %15
|
||||
%void = OpTypeVoid
|
||||
%17 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %17
|
||||
%20 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat4x2(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0);
|
|
@ -0,0 +1,4 @@
|
|||
let m = mat4x2(vec2<f32>(0.0, 1.0),
|
||||
vec2<f32>(2.0, 3.0),
|
||||
vec2<f32>(4.0, 5.0),
|
||||
vec2<f32>(6.0, 7.0));
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float4x2 m = float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float4x2 m = float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
|
|
@ -0,0 +1,33 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 21
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%mat4v2float = OpTypeMatrix %v2float 4
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%6 = OpConstantComposite %v2float %float_0 %float_1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%9 = OpConstantComposite %v2float %float_2 %float_3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%12 = OpConstantComposite %v2float %float_4 %float_5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%15 = OpConstantComposite %v2float %float_6 %float_7
|
||||
%m = OpConstantComposite %mat4v2float %6 %9 %12 %15
|
||||
%void = OpTypeVoid
|
||||
%17 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %17
|
||||
%20 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat4x2(vec2<f32>(0.0, 1.0), vec2<f32>(2.0, 3.0), vec2<f32>(4.0, 5.0), vec2<f32>(6.0, 7.0));
|
|
@ -0,0 +1,4 @@
|
|||
let m = mat4x3(0.0, 1.0, 2.0,
|
||||
3.0, 4.0, 5.0,
|
||||
6.0, 7.0, 8.0,
|
||||
9.0, 10.0, 11.0);
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float4x3 m = float4x3(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f);
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float4x3 m = float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
|
|
@ -0,0 +1,37 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 25
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v3float = OpTypeVector %float 3
|
||||
%mat4v3float = OpTypeMatrix %v3float 4
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
|
||||
%float_3 = OpConstant %float 3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%11 = OpConstantComposite %v3float %float_3 %float_4 %float_5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%float_8 = OpConstant %float 8
|
||||
%15 = OpConstantComposite %v3float %float_6 %float_7 %float_8
|
||||
%float_9 = OpConstant %float 9
|
||||
%float_10 = OpConstant %float 10
|
||||
%float_11 = OpConstant %float 11
|
||||
%19 = OpConstantComposite %v3float %float_9 %float_10 %float_11
|
||||
%m = OpConstantComposite %mat4v3float %7 %11 %15 %19
|
||||
%void = OpTypeVoid
|
||||
%21 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %21
|
||||
%24 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat4x3(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0);
|
|
@ -0,0 +1,4 @@
|
|||
let m = mat4x3(vec3<f32>(0.0, 1.0, 2.0),
|
||||
vec3<f32>(3.0, 4.0, 5.0),
|
||||
vec3<f32>(6.0, 7.0, 8.0),
|
||||
vec3<f32>(9.0, 10.0, 11.0));
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float4x3 m = float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float4x3 m = float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
|
|
@ -0,0 +1,37 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 25
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v3float = OpTypeVector %float 3
|
||||
%mat4v3float = OpTypeMatrix %v3float 4
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
|
||||
%float_3 = OpConstant %float 3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%11 = OpConstantComposite %v3float %float_3 %float_4 %float_5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%float_8 = OpConstant %float 8
|
||||
%15 = OpConstantComposite %v3float %float_6 %float_7 %float_8
|
||||
%float_9 = OpConstant %float 9
|
||||
%float_10 = OpConstant %float 10
|
||||
%float_11 = OpConstant %float 11
|
||||
%19 = OpConstantComposite %v3float %float_9 %float_10 %float_11
|
||||
%m = OpConstantComposite %mat4v3float %7 %11 %15 %19
|
||||
%void = OpTypeVoid
|
||||
%21 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %21
|
||||
%24 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat4x3(vec3<f32>(0.0, 1.0, 2.0), vec3<f32>(3.0, 4.0, 5.0), vec3<f32>(6.0, 7.0, 8.0), vec3<f32>(9.0, 10.0, 11.0));
|
|
@ -0,0 +1,4 @@
|
|||
let m = mat4x4(0.0, 1.0, 2.0, 3.0,
|
||||
4.0, 5.0, 6.0, 7.0,
|
||||
8.0, 9.0, 10.0, 11.0,
|
||||
12.0, 13.0, 14.0, 15.0);
|
|
@ -0,0 +1,6 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
static const float4x4 m = float4x4(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f);
|
|
@ -0,0 +1,4 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
constant float4x4 m = float4x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f), float4(12.0f, 13.0f, 14.0f, 15.0f));
|
|
@ -0,0 +1,41 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 29
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %m "m"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%mat4v4float = OpTypeMatrix %v4float 4
|
||||
%float_0 = OpConstant %float 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_3 = OpConstant %float 3
|
||||
%8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
|
||||
%float_4 = OpConstant %float 4
|
||||
%float_5 = OpConstant %float 5
|
||||
%float_6 = OpConstant %float 6
|
||||
%float_7 = OpConstant %float 7
|
||||
%13 = OpConstantComposite %v4float %float_4 %float_5 %float_6 %float_7
|
||||
%float_8 = OpConstant %float 8
|
||||
%float_9 = OpConstant %float 9
|
||||
%float_10 = OpConstant %float 10
|
||||
%float_11 = OpConstant %float 11
|
||||
%18 = OpConstantComposite %v4float %float_8 %float_9 %float_10 %float_11
|
||||
%float_12 = OpConstant %float 12
|
||||
%float_13 = OpConstant %float 13
|
||||
%float_14 = OpConstant %float 14
|
||||
%float_15 = OpConstant %float 15
|
||||
%23 = OpConstantComposite %v4float %float_12 %float_13 %float_14 %float_15
|
||||
%m = OpConstantComposite %mat4v4float %8 %13 %18 %23
|
||||
%void = OpTypeVoid
|
||||
%25 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %25
|
||||
%28 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1 @@
|
|||
let m = mat4x4(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
|
|
@ -0,0 +1,4 @@
|
|||
let m = mat4x4(vec4<f32>(0.0, 1.0, 2.0, 3.0),
|
||||
vec4<f32>(4.0, 5.0, 6.0, 7.0),
|
||||
vec4<f32>(8.0, 9.0, 10.0, 11.0),
|
||||
vec4<f32>(12.0, 13.0, 14.0, 15.0));
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue