mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 02:39:11 +00:00
Move type base classes into type/ folder.
This CL moves sem/type and copies sem/node into the type/ folder. The type subclasses are moved over to using type::Type while remaining in the sem:: namespace. They will be moved over in followup CLs. Bug: tint:1718 Change-Id: I3f3495328d734f88e4fc2dfbc6705343f1198dc5 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/113180 Reviewed-by: Ben Clayton <bclayton@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
ad71dc1ab2
commit
5f764d8527
51
src/tint/type/array_count.cc
Normal file
51
src/tint/type/array_count.cc
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// 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/tint/type/array_count.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::type::ArrayCount);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::type::ConstantArrayCount);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::type::RuntimeArrayCount);
|
||||
|
||||
namespace tint::type {
|
||||
|
||||
ArrayCount::ArrayCount() : Base() {}
|
||||
ArrayCount::~ArrayCount() = default;
|
||||
|
||||
ConstantArrayCount::ConstantArrayCount(uint32_t val) : Base(), value(val) {}
|
||||
ConstantArrayCount::~ConstantArrayCount() = default;
|
||||
|
||||
size_t ConstantArrayCount::Hash() const {
|
||||
return static_cast<size_t>(TypeInfo::Of<ConstantArrayCount>().full_hashcode);
|
||||
}
|
||||
|
||||
bool ConstantArrayCount::Equals(const ArrayCount& other) const {
|
||||
if (auto* v = other.As<ConstantArrayCount>()) {
|
||||
return value == v->value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RuntimeArrayCount::RuntimeArrayCount() : Base() {}
|
||||
RuntimeArrayCount::~RuntimeArrayCount() = default;
|
||||
|
||||
size_t RuntimeArrayCount::Hash() const {
|
||||
return static_cast<size_t>(TypeInfo::Of<RuntimeArrayCount>().full_hashcode);
|
||||
}
|
||||
|
||||
bool RuntimeArrayCount::Equals(const ArrayCount& other) const {
|
||||
return other.Is<RuntimeArrayCount>();
|
||||
}
|
||||
|
||||
} // namespace tint::type
|
||||
108
src/tint/type/array_count.h
Normal file
108
src/tint/type/array_count.h
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// 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_TINT_TYPE_ARRAY_COUNT_H_
|
||||
#define SRC_TINT_TYPE_ARRAY_COUNT_H_
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "src/tint/type/node.h"
|
||||
|
||||
namespace tint::type {
|
||||
|
||||
/// An array count
|
||||
class ArrayCount : public Castable<ArrayCount, Node> {
|
||||
public:
|
||||
~ArrayCount() override;
|
||||
|
||||
/// @returns a hash of the array count.
|
||||
virtual size_t Hash() const = 0;
|
||||
|
||||
/// @param t other array count
|
||||
/// @returns true if this array count is equal to the given array count
|
||||
virtual bool Equals(const ArrayCount& t) const = 0;
|
||||
|
||||
protected:
|
||||
ArrayCount();
|
||||
};
|
||||
|
||||
/// The variant of an ArrayCount when the array is a const-expression.
|
||||
/// Example:
|
||||
/// ```
|
||||
/// const N = 123;
|
||||
/// type arr = array<i32, N>
|
||||
/// ```
|
||||
class ConstantArrayCount final : public Castable<ConstantArrayCount, ArrayCount> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param val the constant-expression value
|
||||
explicit ConstantArrayCount(uint32_t val);
|
||||
~ConstantArrayCount() override;
|
||||
|
||||
/// @returns a hash of the array count.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param t other array count
|
||||
/// @returns true if this array count is equal to the given array count
|
||||
bool Equals(const ArrayCount& t) const override;
|
||||
|
||||
/// The array count constant-expression value.
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
/// The variant of an ArrayCount when the array is is runtime-sized.
|
||||
/// Example:
|
||||
/// ```
|
||||
/// type arr = array<i32>
|
||||
/// ```
|
||||
class RuntimeArrayCount final : public Castable<RuntimeArrayCount, ArrayCount> {
|
||||
public:
|
||||
/// Constructor
|
||||
RuntimeArrayCount();
|
||||
~RuntimeArrayCount() override;
|
||||
|
||||
/// @returns a hash of the array count.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param t other array count
|
||||
/// @returns true if this array count is equal to the given array count
|
||||
bool Equals(const ArrayCount& t) const override;
|
||||
};
|
||||
|
||||
} // namespace tint::type
|
||||
|
||||
namespace std {
|
||||
|
||||
/// std::hash specialization for tint::type::ArrayCount
|
||||
template <>
|
||||
struct hash<tint::type::ArrayCount> {
|
||||
/// @param a the array count to obtain a hash from
|
||||
/// @returns the hash of the array count
|
||||
size_t operator()(const tint::type::ArrayCount& a) const { return a.Hash(); }
|
||||
};
|
||||
|
||||
/// std::equal_to specialization for tint::type::ArrayCount
|
||||
template <>
|
||||
struct equal_to<tint::type::ArrayCount> {
|
||||
/// @param a the first array count to compare
|
||||
/// @param b the second array count to compare
|
||||
/// @returns true if the two array counts are equal
|
||||
bool operator()(const tint::type::ArrayCount& a, const tint::type::ArrayCount& b) const {
|
||||
return a.Equals(b);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // SRC_TINT_TYPE_ARRAY_COUNT_H_
|
||||
27
src/tint/type/node.cc
Normal file
27
src/tint/type/node.cc
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// 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/tint/type/node.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::type::Node);
|
||||
|
||||
namespace tint::type {
|
||||
|
||||
Node::Node() = default;
|
||||
|
||||
Node::Node(const Node&) = default;
|
||||
|
||||
Node::~Node() = default;
|
||||
|
||||
} // namespace tint::type
|
||||
37
src/tint/type/node.h
Normal file
37
src/tint/type/node.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// 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_TINT_TYPE_NODE_H_
|
||||
#define SRC_TINT_TYPE_NODE_H_
|
||||
|
||||
#include "src/tint/castable.h"
|
||||
|
||||
namespace tint::type {
|
||||
|
||||
/// Node is the base class for all type nodes
|
||||
class Node : public Castable<Node> {
|
||||
public:
|
||||
/// Constructor
|
||||
Node();
|
||||
|
||||
/// Copy constructor
|
||||
Node(const Node&);
|
||||
|
||||
/// Destructor
|
||||
~Node() override;
|
||||
};
|
||||
|
||||
} // namespace tint::type
|
||||
|
||||
#endif // SRC_TINT_TYPE_NODE_H_
|
||||
59
src/tint/type/test_helper.h
Normal file
59
src/tint/type/test_helper.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// 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_TINT_TYPE_TEST_HELPER_H_
|
||||
#define SRC_TINT_TYPE_TEST_HELPER_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/tint/program_builder.h"
|
||||
|
||||
namespace tint::type {
|
||||
|
||||
/// Helper class for testing
|
||||
template <typename BASE>
|
||||
class TestHelperBase : public BASE, public ProgramBuilder {
|
||||
public:
|
||||
/// Builds and returns the program. Must only be called once per test
|
||||
/// @return the built program
|
||||
Program Build() {
|
||||
diag::Formatter formatter;
|
||||
[&]() {
|
||||
ASSERT_TRUE(IsValid()) << "Builder program is not valid\n"
|
||||
<< formatter.format(Diagnostics());
|
||||
}();
|
||||
return Program(std::move(*this));
|
||||
}
|
||||
};
|
||||
using TestHelper = TestHelperBase<testing::Test>;
|
||||
|
||||
template <typename T>
|
||||
using TestParamHelper = TestHelperBase<testing::TestWithParam<T>>;
|
||||
|
||||
} // namespace tint::type
|
||||
|
||||
/// Helper macro for testing that a type was as expected
|
||||
#define EXPECT_TYPE(GOT, EXPECT) \
|
||||
do { \
|
||||
const type::Type* got = GOT; \
|
||||
const type::Type* expect = EXPECT; \
|
||||
if (got != expect) { \
|
||||
ADD_FAILURE() << #GOT " != " #EXPECT "\n" \
|
||||
<< " " #GOT ": " << FriendlyName(got) << "\n" \
|
||||
<< " " #EXPECT ": " << FriendlyName(expect); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#endif // SRC_TINT_TYPE_TEST_HELPER_H_
|
||||
329
src/tint/type/type.cc
Normal file
329
src/tint/type/type.cc
Normal file
@@ -0,0 +1,329 @@
|
||||
// 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/tint/type/type.h"
|
||||
|
||||
#include "src/tint/sem/abstract_float.h"
|
||||
#include "src/tint/sem/abstract_int.h"
|
||||
#include "src/tint/sem/array.h"
|
||||
#include "src/tint/sem/bool.h"
|
||||
#include "src/tint/sem/f16.h"
|
||||
#include "src/tint/sem/f32.h"
|
||||
#include "src/tint/sem/i32.h"
|
||||
#include "src/tint/sem/matrix.h"
|
||||
#include "src/tint/sem/pointer.h"
|
||||
#include "src/tint/sem/reference.h"
|
||||
#include "src/tint/sem/sampler.h"
|
||||
#include "src/tint/sem/struct.h"
|
||||
#include "src/tint/sem/texture.h"
|
||||
#include "src/tint/sem/u32.h"
|
||||
#include "src/tint/sem/vector.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::type::Type);
|
||||
|
||||
namespace tint::type {
|
||||
|
||||
Type::Type(TypeFlags flags) : flags_(flags) {
|
||||
if (IsConstructible()) {
|
||||
TINT_ASSERT(Type, HasCreationFixedFootprint());
|
||||
}
|
||||
}
|
||||
|
||||
Type::Type(Type&&) = default;
|
||||
|
||||
Type::~Type() = default;
|
||||
|
||||
const Type* Type::UnwrapPtr() const {
|
||||
auto* type = this;
|
||||
while (auto* ptr = type->As<sem::Pointer>()) {
|
||||
type = ptr->StoreType();
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
const Type* Type::UnwrapRef() const {
|
||||
auto* type = this;
|
||||
if (auto* ref = type->As<sem::Reference>()) {
|
||||
type = ref->StoreType();
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
uint32_t Type::Size() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Type::Align() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Type::is_scalar() const {
|
||||
return IsAnyOf<sem::F16, sem::F32, sem::U32, sem::I32, sem::AbstractNumeric, sem::Bool>();
|
||||
}
|
||||
|
||||
bool Type::is_numeric_scalar() const {
|
||||
return IsAnyOf<sem::F16, sem::F32, sem::U32, sem::I32, sem::AbstractNumeric>();
|
||||
}
|
||||
|
||||
bool Type::is_float_scalar() const {
|
||||
return IsAnyOf<sem::F16, sem::F32, sem::AbstractNumeric>();
|
||||
}
|
||||
|
||||
bool Type::is_float_matrix() const {
|
||||
return Is([](const sem::Matrix* m) { return m->type()->is_float_scalar(); });
|
||||
}
|
||||
|
||||
bool Type::is_square_float_matrix() const {
|
||||
return Is([](const sem::Matrix* m) {
|
||||
return m->type()->is_float_scalar() && m->rows() == m->columns();
|
||||
});
|
||||
}
|
||||
|
||||
bool Type::is_float_vector() const {
|
||||
return Is([](const sem::Vector* v) { return v->type()->is_float_scalar(); });
|
||||
}
|
||||
|
||||
bool Type::is_float_scalar_or_vector() const {
|
||||
return is_float_scalar() || is_float_vector();
|
||||
}
|
||||
|
||||
bool Type::is_float_scalar_or_vector_or_matrix() const {
|
||||
return is_float_scalar() || is_float_vector() || is_float_matrix();
|
||||
}
|
||||
|
||||
bool Type::is_integer_scalar() const {
|
||||
return IsAnyOf<sem::U32, sem::I32>();
|
||||
}
|
||||
|
||||
bool Type::is_signed_integer_scalar() const {
|
||||
return IsAnyOf<sem::I32, sem::AbstractInt>();
|
||||
}
|
||||
|
||||
bool Type::is_unsigned_integer_scalar() const {
|
||||
return Is<sem::U32>();
|
||||
}
|
||||
|
||||
bool Type::is_signed_integer_vector() const {
|
||||
return Is(
|
||||
[](const sem::Vector* v) { return v->type()->IsAnyOf<sem::I32, sem::AbstractInt>(); });
|
||||
}
|
||||
|
||||
bool Type::is_unsigned_integer_vector() const {
|
||||
return Is([](const sem::Vector* v) { return v->type()->Is<sem::U32>(); });
|
||||
}
|
||||
|
||||
bool Type::is_unsigned_integer_scalar_or_vector() const {
|
||||
return Is<sem::U32>() || is_unsigned_integer_vector();
|
||||
}
|
||||
|
||||
bool Type::is_signed_integer_scalar_or_vector() const {
|
||||
return IsAnyOf<sem::I32, sem::AbstractInt>() || is_signed_integer_vector();
|
||||
}
|
||||
|
||||
bool Type::is_integer_scalar_or_vector() const {
|
||||
return is_unsigned_integer_scalar_or_vector() || is_signed_integer_scalar_or_vector();
|
||||
}
|
||||
|
||||
bool Type::is_abstract_integer_vector() const {
|
||||
return Is([](const sem::Vector* v) { return v->type()->Is<sem::AbstractInt>(); });
|
||||
}
|
||||
|
||||
bool Type::is_abstract_float_vector() const {
|
||||
return Is([](const sem::Vector* v) { return v->type()->Is<sem::AbstractFloat>(); });
|
||||
}
|
||||
|
||||
bool Type::is_abstract_integer_scalar_or_vector() const {
|
||||
return Is<sem::AbstractInt>() || is_abstract_integer_vector();
|
||||
}
|
||||
|
||||
bool Type::is_abstract_float_scalar_or_vector() const {
|
||||
return Is<sem::AbstractFloat>() || is_abstract_float_vector();
|
||||
}
|
||||
|
||||
bool Type::is_bool_vector() const {
|
||||
return Is([](const sem::Vector* v) { return v->type()->Is<sem::Bool>(); });
|
||||
}
|
||||
|
||||
bool Type::is_bool_scalar_or_vector() const {
|
||||
return Is<sem::Bool>() || is_bool_vector();
|
||||
}
|
||||
|
||||
bool Type::is_numeric_vector() const {
|
||||
return Is([](const sem::Vector* v) { return v->type()->is_numeric_scalar(); });
|
||||
}
|
||||
|
||||
bool Type::is_scalar_vector() const {
|
||||
return Is([](const sem::Vector* v) { return v->type()->is_scalar(); });
|
||||
}
|
||||
|
||||
bool Type::is_numeric_scalar_or_vector() const {
|
||||
return is_numeric_scalar() || is_numeric_vector();
|
||||
}
|
||||
|
||||
bool Type::is_handle() const {
|
||||
return IsAnyOf<sem::Sampler, sem::Texture>();
|
||||
}
|
||||
|
||||
bool Type::HoldsAbstract() const {
|
||||
return Switch(
|
||||
this, //
|
||||
[&](const sem::AbstractNumeric*) { return true; },
|
||||
[&](const sem::Vector* v) { return v->type()->HoldsAbstract(); },
|
||||
[&](const sem::Matrix* m) { return m->type()->HoldsAbstract(); },
|
||||
[&](const sem::Array* a) { return a->ElemType()->HoldsAbstract(); },
|
||||
[&](const sem::Struct* s) {
|
||||
for (auto* m : s->Members()) {
|
||||
if (m->Type()->HoldsAbstract()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
uint32_t Type::ConversionRank(const Type* from, const Type* to) {
|
||||
if (from->UnwrapRef() == to) {
|
||||
return 0;
|
||||
}
|
||||
return Switch(
|
||||
from,
|
||||
[&](const sem::AbstractFloat*) {
|
||||
return Switch(
|
||||
to, //
|
||||
[&](const sem::F32*) { return 1; }, //
|
||||
[&](const sem::F16*) { return 2; }, //
|
||||
[&](Default) { return kNoConversion; });
|
||||
},
|
||||
[&](const sem::AbstractInt*) {
|
||||
return Switch(
|
||||
to, //
|
||||
[&](const sem::I32*) { return 3; }, //
|
||||
[&](const sem::U32*) { return 4; }, //
|
||||
[&](const sem::AbstractFloat*) { return 5; }, //
|
||||
[&](const sem::F32*) { return 6; }, //
|
||||
[&](const sem::F16*) { return 7; }, //
|
||||
[&](Default) { return kNoConversion; });
|
||||
},
|
||||
[&](const sem::Vector* from_vec) {
|
||||
if (auto* to_vec = to->As<sem::Vector>()) {
|
||||
if (from_vec->Width() == to_vec->Width()) {
|
||||
return ConversionRank(from_vec->type(), to_vec->type());
|
||||
}
|
||||
}
|
||||
return kNoConversion;
|
||||
},
|
||||
[&](const sem::Matrix* from_mat) {
|
||||
if (auto* to_mat = to->As<sem::Matrix>()) {
|
||||
if (from_mat->columns() == to_mat->columns() &&
|
||||
from_mat->rows() == to_mat->rows()) {
|
||||
return ConversionRank(from_mat->type(), to_mat->type());
|
||||
}
|
||||
}
|
||||
return kNoConversion;
|
||||
},
|
||||
[&](const sem::Array* from_arr) {
|
||||
if (auto* to_arr = to->As<sem::Array>()) {
|
||||
if (from_arr->Count() == to_arr->Count()) {
|
||||
return ConversionRank(from_arr->ElemType(), to_arr->ElemType());
|
||||
}
|
||||
}
|
||||
return kNoConversion;
|
||||
},
|
||||
[&](const sem::Struct* from_str) {
|
||||
auto concrete_tys = from_str->ConcreteTypes();
|
||||
for (size_t i = 0; i < concrete_tys.Length(); i++) {
|
||||
if (concrete_tys[i] == to) {
|
||||
return static_cast<uint32_t>(i + 1);
|
||||
}
|
||||
}
|
||||
return kNoConversion;
|
||||
},
|
||||
[&](Default) { return kNoConversion; });
|
||||
}
|
||||
|
||||
const Type* Type::ElementOf(const Type* ty, uint32_t* count /* = nullptr */) {
|
||||
if (ty->is_scalar()) {
|
||||
if (count) {
|
||||
*count = 1;
|
||||
}
|
||||
return ty;
|
||||
}
|
||||
return Switch(
|
||||
ty, //
|
||||
[&](const sem::Vector* v) {
|
||||
if (count) {
|
||||
*count = v->Width();
|
||||
}
|
||||
return v->type();
|
||||
},
|
||||
[&](const sem::Matrix* m) {
|
||||
if (count) {
|
||||
*count = m->columns();
|
||||
}
|
||||
return m->ColumnType();
|
||||
},
|
||||
[&](const sem::Array* a) {
|
||||
if (count) {
|
||||
if (auto* const_count = a->Count()->As<type::ConstantArrayCount>()) {
|
||||
*count = const_count->value;
|
||||
}
|
||||
}
|
||||
return a->ElemType();
|
||||
},
|
||||
[&](Default) {
|
||||
if (count) {
|
||||
*count = 1;
|
||||
}
|
||||
return ty;
|
||||
});
|
||||
}
|
||||
|
||||
const Type* Type::DeepestElementOf(const Type* ty, uint32_t* count /* = nullptr */) {
|
||||
auto el_ty = ElementOf(ty, count);
|
||||
while (el_ty && ty != el_ty) {
|
||||
ty = el_ty;
|
||||
|
||||
uint32_t n = 0;
|
||||
el_ty = ElementOf(ty, &n);
|
||||
if (count) {
|
||||
*count *= n;
|
||||
}
|
||||
}
|
||||
return el_ty;
|
||||
}
|
||||
|
||||
const type::Type* Type::Common(utils::VectorRef<const Type*> types) {
|
||||
const auto count = types.Length();
|
||||
if (count == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto* common = types[0];
|
||||
for (size_t i = 1; i < count; i++) {
|
||||
auto* ty = types[i];
|
||||
if (ty == common) {
|
||||
continue; // ty == common
|
||||
}
|
||||
if (type::Type::ConversionRank(ty, common) != type::Type::kNoConversion) {
|
||||
continue; // ty can be converted to common.
|
||||
}
|
||||
if (type::Type::ConversionRank(common, ty) != type::Type::kNoConversion) {
|
||||
common = ty; // common can be converted to ty.
|
||||
continue;
|
||||
}
|
||||
return nullptr; // Conversion is not valid.
|
||||
}
|
||||
return common;
|
||||
}
|
||||
|
||||
} // namespace tint::type
|
||||
231
src/tint/type/type.h
Normal file
231
src/tint/type/type.h
Normal file
@@ -0,0 +1,231 @@
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// 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_TINT_TYPE_TYPE_H_
|
||||
#define SRC_TINT_TYPE_TYPE_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/type/node.h"
|
||||
#include "src/tint/utils/enum_set.h"
|
||||
#include "src/tint/utils/vector.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint {
|
||||
class ProgramBuilder;
|
||||
class SymbolTable;
|
||||
} // namespace tint
|
||||
|
||||
namespace tint::type {
|
||||
|
||||
enum TypeFlag {
|
||||
/// Type is constructable.
|
||||
/// @see https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
|
||||
kConstructable,
|
||||
/// Type has a creation-fixed footprint.
|
||||
/// @see https://www.w3.org/TR/WGSL/#fixed-footprint-types
|
||||
kCreationFixedFootprint,
|
||||
/// Type has a fixed footprint.
|
||||
/// @see https://www.w3.org/TR/WGSL/#fixed-footprint-types
|
||||
kFixedFootprint,
|
||||
};
|
||||
|
||||
/// An alias to utils::EnumSet<TypeFlag>
|
||||
using TypeFlags = utils::EnumSet<TypeFlag>;
|
||||
|
||||
/// Base class for a type in the system
|
||||
class Type : public Castable<Type, Node> {
|
||||
public:
|
||||
/// Alias to TypeFlag
|
||||
using Flag = TypeFlag;
|
||||
|
||||
/// Move constructor
|
||||
Type(Type&&);
|
||||
~Type() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
virtual size_t Hash() const = 0;
|
||||
|
||||
/// @returns true if the this type is equal to the given type
|
||||
virtual bool Equals(const Type&) const = 0;
|
||||
|
||||
/// @param symbols the program's symbol table
|
||||
/// @returns the name for this type that closely resembles how it would be
|
||||
/// declared in WGSL.
|
||||
virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;
|
||||
|
||||
/// @returns the inner most pointee type if this is a pointer, `this`
|
||||
/// otherwise
|
||||
const Type* UnwrapPtr() const;
|
||||
|
||||
/// @returns the inner type if this is a reference, `this` otherwise
|
||||
const Type* UnwrapRef() const;
|
||||
|
||||
/// @returns the size in bytes of the type. This may include tail padding.
|
||||
/// @note opaque types will return a size of 0.
|
||||
virtual uint32_t Size() const;
|
||||
|
||||
/// @returns the alignment in bytes of the type. This may include tail
|
||||
/// padding.
|
||||
/// @note opaque types will return a size of 0.
|
||||
virtual uint32_t Align() const;
|
||||
|
||||
/// @returns the flags on the type
|
||||
TypeFlags Flags() { return flags_; }
|
||||
|
||||
/// @returns true if type is constructable
|
||||
/// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
|
||||
inline bool IsConstructible() const { return flags_.Contains(Flag::kConstructable); }
|
||||
|
||||
/// @returns true has a creation-fixed footprint.
|
||||
/// @see https://www.w3.org/TR/WGSL/#fixed-footprint-types
|
||||
inline bool HasCreationFixedFootprint() const {
|
||||
return flags_.Contains(Flag::kCreationFixedFootprint);
|
||||
}
|
||||
|
||||
/// @returns true has a fixed footprint.
|
||||
/// @see https://www.w3.org/TR/WGSL/#fixed-footprint-types
|
||||
inline bool HasFixedFootprint() const { return flags_.Contains(Flag::kFixedFootprint); }
|
||||
|
||||
/// @returns true if this type is a scalar
|
||||
bool is_scalar() const;
|
||||
/// @returns true if this type is a numeric scalar
|
||||
bool is_numeric_scalar() const;
|
||||
/// @returns true if this type is a float scalar
|
||||
bool is_float_scalar() const;
|
||||
/// @returns true if this type is a float matrix
|
||||
bool is_float_matrix() const;
|
||||
/// @returns true if this type is a square float matrix
|
||||
bool is_square_float_matrix() const;
|
||||
/// @returns true if this type is a float vector
|
||||
bool is_float_vector() const;
|
||||
/// @returns true if this type is a float scalar or vector
|
||||
bool is_float_scalar_or_vector() const;
|
||||
/// @returns true if this type is a float scalar or vector or matrix
|
||||
bool is_float_scalar_or_vector_or_matrix() const;
|
||||
/// @returns true if this type is an integer scalar
|
||||
bool is_integer_scalar() const;
|
||||
/// @returns true if this type is a signed integer scalar
|
||||
bool is_signed_integer_scalar() const;
|
||||
/// @returns true if this type is an unsigned integer scalar
|
||||
bool is_unsigned_integer_scalar() const;
|
||||
/// @returns true if this type is a signed integer vector
|
||||
bool is_signed_integer_vector() const;
|
||||
/// @returns true if this type is an unsigned vector
|
||||
bool is_unsigned_integer_vector() const;
|
||||
/// @returns true if this type is an unsigned scalar or vector
|
||||
bool is_unsigned_integer_scalar_or_vector() const;
|
||||
/// @returns true if this type is a signed scalar or vector
|
||||
bool is_signed_integer_scalar_or_vector() const;
|
||||
/// @returns true if this type is an integer scalar or vector
|
||||
bool is_integer_scalar_or_vector() const;
|
||||
/// @returns true if this type is an abstract integer vector
|
||||
bool is_abstract_integer_vector() const;
|
||||
/// @returns true if this type is an abstract float vector
|
||||
bool is_abstract_float_vector() const;
|
||||
/// @returns true if this type is an abstract integer scalar or vector
|
||||
bool is_abstract_integer_scalar_or_vector() const;
|
||||
/// @returns true if this type is an abstract float scalar or vector
|
||||
bool is_abstract_float_scalar_or_vector() const;
|
||||
/// @returns true if this type is a boolean vector
|
||||
bool is_bool_vector() const;
|
||||
/// @returns true if this type is boolean scalar or vector
|
||||
bool is_bool_scalar_or_vector() const;
|
||||
/// @returns true if this type is a numeric vector
|
||||
bool is_numeric_vector() const;
|
||||
/// @returns true if this type is a vector of scalar type
|
||||
bool is_scalar_vector() const;
|
||||
/// @returns true if this type is a numeric scale or vector
|
||||
bool is_numeric_scalar_or_vector() const;
|
||||
/// @returns true if this type is a handle type
|
||||
bool is_handle() const;
|
||||
|
||||
/// @returns true if this type is an abstract-numeric or if the type holds an element that is an
|
||||
/// abstract-numeric.
|
||||
bool HoldsAbstract() const;
|
||||
|
||||
/// kNoConversion is returned from ConversionRank() when the implicit conversion is not
|
||||
/// permitted.
|
||||
static constexpr uint32_t kNoConversion = 0xffffffffu;
|
||||
|
||||
/// ConversionRank returns the implicit conversion rank when attempting to convert `from` to
|
||||
/// `to`. Lower ranks are preferred over higher ranks.
|
||||
/// @param from the source type
|
||||
/// @param to the destination type
|
||||
/// @returns the rank value for converting from type `from` to type `to`, or #kNoConversion if
|
||||
/// the implicit conversion is not allowed.
|
||||
/// @see https://www.w3.org/TR/WGSL/#conversion-rank
|
||||
static uint32_t ConversionRank(const Type* from, const Type* to);
|
||||
|
||||
/// @param ty the type to obtain the element type from
|
||||
/// @param count if not null, then this is assigned the number of child elements in the type.
|
||||
/// For example, the count of an `array<vec3<f32>, 5>` type would be 5.
|
||||
/// @returns
|
||||
/// * the element type if `ty` is a vector or array
|
||||
/// * the column type if `ty` is a matrix
|
||||
/// * `ty` if `ty` is none of the above
|
||||
static const Type* ElementOf(const Type* ty, uint32_t* count = nullptr);
|
||||
|
||||
/// @param ty the type to obtain the deepest element type from
|
||||
/// @param count if not null, then this is assigned the full number of most deeply nested
|
||||
/// elements in the type. For example, the count of an `array<vec3<f32>, 5>` type would be 15.
|
||||
/// @returns
|
||||
/// * the element type if `ty` is a vector
|
||||
/// * the matrix element type if `ty` is a matrix
|
||||
/// * the deepest element type if `ty` is an array
|
||||
/// * `ty` if `ty` is none of the above
|
||||
static const Type* DeepestElementOf(const Type* ty, uint32_t* count = nullptr);
|
||||
|
||||
/// @param types the list of types
|
||||
/// @returns the lowest-ranking type that all types in `types` can be implicitly converted to,
|
||||
/// or nullptr if there is no consistent common type across all types in `types`.
|
||||
/// @see https://www.w3.org/TR/WGSL/#conversion-rank
|
||||
static const type::Type* Common(utils::VectorRef<const Type*> types);
|
||||
|
||||
protected:
|
||||
/// Constructor
|
||||
/// @param flags the flags of this type
|
||||
explicit Type(TypeFlags flags);
|
||||
|
||||
/// The flags of this type.
|
||||
const TypeFlags flags_;
|
||||
};
|
||||
|
||||
} // namespace tint::type
|
||||
|
||||
namespace std {
|
||||
|
||||
/// std::hash specialization for tint::type::Type
|
||||
template <>
|
||||
struct hash<tint::type::Type> {
|
||||
/// @param type the type to obtain a hash from
|
||||
/// @returns the hash of the type
|
||||
size_t operator()(const tint::type::Type& type) const { return type.Hash(); }
|
||||
};
|
||||
|
||||
/// std::equal_to specialization for tint::type::Type
|
||||
template <>
|
||||
struct equal_to<tint::type::Type> {
|
||||
/// @param a the first type to compare
|
||||
/// @param b the second type to compare
|
||||
/// @returns true if the two types are equal
|
||||
bool operator()(const tint::type::Type& a, const tint::type::Type& b) const {
|
||||
return a.Equals(b);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // SRC_TINT_TYPE_TYPE_H_
|
||||
617
src/tint/type/type_test.cc
Normal file
617
src/tint/type/type_test.cc
Normal file
@@ -0,0 +1,617 @@
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// 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/tint/sem/abstract_float.h"
|
||||
#include "src/tint/sem/abstract_int.h"
|
||||
#include "src/tint/sem/f16.h"
|
||||
#include "src/tint/sem/reference.h"
|
||||
#include "src/tint/type/array_count.h"
|
||||
#include "src/tint/type/test_helper.h"
|
||||
|
||||
namespace tint::type {
|
||||
namespace {
|
||||
|
||||
struct TypeTest : public TestHelper {
|
||||
const sem::AbstractFloat* af = create<sem::AbstractFloat>();
|
||||
const sem::AbstractInt* ai = create<sem::AbstractInt>();
|
||||
const sem::F32* f32 = create<sem::F32>();
|
||||
const sem::F16* f16 = create<sem::F16>();
|
||||
const sem::I32* i32 = create<sem::I32>();
|
||||
const sem::U32* u32 = create<sem::U32>();
|
||||
const sem::Vector* vec2_f32 = create<sem::Vector>(f32, 2u);
|
||||
const sem::Vector* vec3_f32 = create<sem::Vector>(f32, 3u);
|
||||
const sem::Vector* vec3_f16 = create<sem::Vector>(f16, 3u);
|
||||
const sem::Vector* vec4_f32 = create<sem::Vector>(f32, 4u);
|
||||
const sem::Vector* vec3_u32 = create<sem::Vector>(u32, 3u);
|
||||
const sem::Vector* vec3_i32 = create<sem::Vector>(i32, 3u);
|
||||
const sem::Vector* vec3_af = create<sem::Vector>(af, 3u);
|
||||
const sem::Vector* vec3_ai = create<sem::Vector>(ai, 3u);
|
||||
const sem::Matrix* mat2x4_f32 = create<sem::Matrix>(vec4_f32, 2u);
|
||||
const sem::Matrix* mat3x4_f32 = create<sem::Matrix>(vec4_f32, 3u);
|
||||
const sem::Matrix* mat4x2_f32 = create<sem::Matrix>(vec2_f32, 4u);
|
||||
const sem::Matrix* mat4x3_f32 = create<sem::Matrix>(vec3_f32, 4u);
|
||||
const sem::Matrix* mat4x3_f16 = create<sem::Matrix>(vec3_f16, 4u);
|
||||
const sem::Matrix* mat4x3_af = create<sem::Matrix>(vec3_af, 4u);
|
||||
const sem::Reference* ref_u32 =
|
||||
create<sem::Reference>(u32, ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
|
||||
const sem::Struct* str_f32 = create<sem::Struct>(nullptr,
|
||||
Source{},
|
||||
Sym("str_f32"),
|
||||
utils::Vector{
|
||||
create<sem::StructMember>(
|
||||
/* declaration */ nullptr,
|
||||
/* source */ Source{},
|
||||
/* name */ Sym("x"),
|
||||
/* type */ f32,
|
||||
/* index */ 0u,
|
||||
/* offset */ 0u,
|
||||
/* align */ 4u,
|
||||
/* size */ 4u,
|
||||
/* location */ std::nullopt),
|
||||
},
|
||||
/* align*/ 4u,
|
||||
/* size*/ 4u,
|
||||
/* size_no_padding*/ 4u);
|
||||
const sem::Struct* str_f16 = create<sem::Struct>(nullptr,
|
||||
Source{},
|
||||
Sym("str_f16"),
|
||||
utils::Vector{
|
||||
create<sem::StructMember>(
|
||||
/* declaration */ nullptr,
|
||||
/* source */ Source{},
|
||||
/* name */ Sym("x"),
|
||||
/* type */ f16,
|
||||
/* index */ 0u,
|
||||
/* offset */ 0u,
|
||||
/* align */ 4u,
|
||||
/* size */ 4u,
|
||||
/* location */ std::nullopt),
|
||||
},
|
||||
/* align*/ 4u,
|
||||
/* size*/ 4u,
|
||||
/* size_no_padding*/ 4u);
|
||||
sem::Struct* str_af = create<sem::Struct>(nullptr,
|
||||
Source{},
|
||||
Sym("str_af"),
|
||||
utils::Vector{
|
||||
create<sem::StructMember>(
|
||||
/* declaration */ nullptr,
|
||||
/* source */ Source{},
|
||||
/* name */ Sym("x"),
|
||||
/* type */ af,
|
||||
/* index */ 0u,
|
||||
/* offset */ 0u,
|
||||
/* align */ 4u,
|
||||
/* size */ 4u,
|
||||
/* location */ std::nullopt),
|
||||
},
|
||||
/* align*/ 4u,
|
||||
/* size*/ 4u,
|
||||
/* size_no_padding*/ 4u);
|
||||
const sem::Array* arr_i32 = create<sem::Array>(
|
||||
/* element */ i32,
|
||||
/* count */ create<type::ConstantArrayCount>(5u),
|
||||
/* align */ 4u,
|
||||
/* size */ 5u * 4u,
|
||||
/* stride */ 5u * 4u,
|
||||
/* implicit_stride */ 5u * 4u);
|
||||
const sem::Array* arr_ai = create<sem::Array>(
|
||||
/* element */ ai,
|
||||
/* count */ create<type::ConstantArrayCount>(5u),
|
||||
/* align */ 4u,
|
||||
/* size */ 5u * 4u,
|
||||
/* stride */ 5u * 4u,
|
||||
/* implicit_stride */ 5u * 4u);
|
||||
const sem::Array* arr_vec3_i32 = create<sem::Array>(
|
||||
/* element */ vec3_i32,
|
||||
/* count */ create<ConstantArrayCount>(5u),
|
||||
/* align */ 16u,
|
||||
/* size */ 5u * 16u,
|
||||
/* stride */ 5u * 16u,
|
||||
/* implicit_stride */ 5u * 16u);
|
||||
const sem::Array* arr_vec3_ai = create<sem::Array>(
|
||||
/* element */ vec3_ai,
|
||||
/* count */ create<type::ConstantArrayCount>(5u),
|
||||
/* align */ 16u,
|
||||
/* size */ 5u * 16u,
|
||||
/* stride */ 5u * 16u,
|
||||
/* implicit_stride */ 5u * 16u);
|
||||
const sem::Array* arr_mat4x3_f16 = create<sem::Array>(
|
||||
/* element */ mat4x3_f16,
|
||||
/* count */ create<type::ConstantArrayCount>(5u),
|
||||
/* align */ 32u,
|
||||
/* size */ 5u * 32u,
|
||||
/* stride */ 5u * 32u,
|
||||
/* implicit_stride */ 5u * 32u);
|
||||
const sem::Array* arr_mat4x3_f32 = create<sem::Array>(
|
||||
/* element */ mat4x3_f32,
|
||||
/* count */ create<type::ConstantArrayCount>(5u),
|
||||
/* align */ 64u,
|
||||
/* size */ 5u * 64u,
|
||||
/* stride */ 5u * 64u,
|
||||
/* implicit_stride */ 5u * 64u);
|
||||
const sem::Array* arr_mat4x3_af = create<sem::Array>(
|
||||
/* element */ mat4x3_af,
|
||||
/* count */ create<type::ConstantArrayCount>(5u),
|
||||
/* align */ 64u,
|
||||
/* size */ 5u * 64u,
|
||||
/* stride */ 5u * 64u,
|
||||
/* implicit_stride */ 5u * 64u);
|
||||
const sem::Array* arr_str_f16 = create<sem::Array>(
|
||||
/* element */ str_f16,
|
||||
/* count */ create<type::ConstantArrayCount>(5u),
|
||||
/* align */ 4u,
|
||||
/* size */ 5u * 4u,
|
||||
/* stride */ 5u * 4u,
|
||||
/* implicit_stride */ 5u * 4u);
|
||||
const sem::Array* arr_str_af = create<sem::Array>(
|
||||
/* element */ str_af,
|
||||
/* count */ create<type::ConstantArrayCount>(5u),
|
||||
/* align */ 4u,
|
||||
/* size */ 5u * 4u,
|
||||
/* stride */ 5u * 4u,
|
||||
/* implicit_stride */ 5u * 4u);
|
||||
|
||||
TypeTest() { str_af->SetConcreteTypes(utils::Vector{str_f32, str_f16}); }
|
||||
};
|
||||
|
||||
TEST_F(TypeTest, ConversionRank) {
|
||||
EXPECT_EQ(Type::ConversionRank(i32, i32), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(f32, f32), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(u32, u32), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_f32, vec3_f32), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_f16, vec3_f16), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec4_f32, vec4_f32), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_u32, vec3_u32), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_i32, vec3_i32), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_af, vec3_af), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_ai, vec3_ai), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(mat3x4_f32, mat3x4_f32), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat4x3_f32), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(mat4x3_f16, mat4x3_f16), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(arr_vec3_ai, arr_vec3_ai), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(arr_mat4x3_f16, arr_mat4x3_f16), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_af), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(arr_mat4x3_af, arr_mat4x3_af), 0u);
|
||||
EXPECT_EQ(Type::ConversionRank(ref_u32, u32), 0u);
|
||||
|
||||
EXPECT_EQ(Type::ConversionRank(af, f32), 1u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_af, vec3_f32), 1u);
|
||||
EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_f32), 1u);
|
||||
EXPECT_EQ(Type::ConversionRank(arr_mat4x3_af, arr_mat4x3_f32), 1u);
|
||||
EXPECT_EQ(Type::ConversionRank(af, f16), 2u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_af, vec3_f16), 2u);
|
||||
EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_f16), 2u);
|
||||
EXPECT_EQ(Type::ConversionRank(arr_mat4x3_af, arr_mat4x3_f16), 2u);
|
||||
EXPECT_EQ(Type::ConversionRank(ai, i32), 3u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_ai, vec3_i32), 3u);
|
||||
EXPECT_EQ(Type::ConversionRank(arr_ai, arr_i32), 3u);
|
||||
EXPECT_EQ(Type::ConversionRank(arr_vec3_ai, arr_vec3_i32), 3u);
|
||||
EXPECT_EQ(Type::ConversionRank(ai, u32), 4u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_ai, vec3_u32), 4u);
|
||||
EXPECT_EQ(Type::ConversionRank(ai, af), 5u);
|
||||
EXPECT_EQ(Type::ConversionRank(ai, f32), 6u);
|
||||
EXPECT_EQ(Type::ConversionRank(ai, f16), 7u);
|
||||
EXPECT_EQ(Type::ConversionRank(str_af, str_f32), 1u);
|
||||
EXPECT_EQ(Type::ConversionRank(str_af, str_f16), 2u);
|
||||
|
||||
EXPECT_EQ(Type::ConversionRank(i32, f32), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(f32, u32), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(u32, i32), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_u32, vec3_f32), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_f32, vec4_f32), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(mat3x4_f32, mat4x3_f32), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat3x4_f32), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat4x3_af), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(arr_vec3_i32, arr_vec3_ai), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(arr_mat4x3_f32, arr_mat4x3_af), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(arr_mat4x3_f16, arr_mat4x3_f32), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(f32, af), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(f16, af), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_f16, vec3_af), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(mat4x3_f16, mat4x3_af), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(i32, af), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(u32, af), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(af, ai), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(f32, ai), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(f16, ai), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(str_f32, str_f16), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(str_f16, str_f32), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(str_f32, str_af), Type::kNoConversion);
|
||||
EXPECT_EQ(Type::ConversionRank(str_f16, str_af), Type::kNoConversion);
|
||||
}
|
||||
|
||||
TEST_F(TypeTest, ElementOf) {
|
||||
// No count
|
||||
EXPECT_TYPE(Type::ElementOf(f32), f32);
|
||||
EXPECT_TYPE(Type::ElementOf(f16), f16);
|
||||
EXPECT_TYPE(Type::ElementOf(i32), i32);
|
||||
EXPECT_TYPE(Type::ElementOf(u32), u32);
|
||||
EXPECT_TYPE(Type::ElementOf(vec2_f32), f32);
|
||||
EXPECT_TYPE(Type::ElementOf(vec3_f16), f16);
|
||||
EXPECT_TYPE(Type::ElementOf(vec4_f32), f32);
|
||||
EXPECT_TYPE(Type::ElementOf(vec3_u32), u32);
|
||||
EXPECT_TYPE(Type::ElementOf(vec3_i32), i32);
|
||||
EXPECT_TYPE(Type::ElementOf(mat2x4_f32), vec4_f32);
|
||||
EXPECT_TYPE(Type::ElementOf(mat4x2_f32), vec2_f32);
|
||||
EXPECT_TYPE(Type::ElementOf(mat4x3_f16), vec3_f16);
|
||||
EXPECT_TYPE(Type::ElementOf(str_f16), str_f16);
|
||||
EXPECT_TYPE(Type::ElementOf(arr_i32), i32);
|
||||
EXPECT_TYPE(Type::ElementOf(arr_vec3_i32), vec3_i32);
|
||||
EXPECT_TYPE(Type::ElementOf(arr_mat4x3_f16), mat4x3_f16);
|
||||
EXPECT_TYPE(Type::ElementOf(arr_mat4x3_af), mat4x3_af);
|
||||
EXPECT_TYPE(Type::ElementOf(arr_str_f16), str_f16);
|
||||
|
||||
// With count
|
||||
uint32_t count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(f32, &count), f32);
|
||||
EXPECT_EQ(count, 1u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(f16, &count), f16);
|
||||
EXPECT_EQ(count, 1u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(i32, &count), i32);
|
||||
EXPECT_EQ(count, 1u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(u32, &count), u32);
|
||||
EXPECT_EQ(count, 1u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(vec2_f32, &count), f32);
|
||||
EXPECT_EQ(count, 2u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(vec3_f16, &count), f16);
|
||||
EXPECT_EQ(count, 3u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(vec4_f32, &count), f32);
|
||||
EXPECT_EQ(count, 4u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(vec3_u32, &count), u32);
|
||||
EXPECT_EQ(count, 3u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(vec3_i32, &count), i32);
|
||||
EXPECT_EQ(count, 3u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(mat2x4_f32, &count), vec4_f32);
|
||||
EXPECT_EQ(count, 2u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(mat4x2_f32, &count), vec2_f32);
|
||||
EXPECT_EQ(count, 4u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(mat4x3_f16, &count), vec3_f16);
|
||||
EXPECT_EQ(count, 4u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(str_f16, &count), str_f16);
|
||||
EXPECT_EQ(count, 1u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(arr_i32, &count), i32);
|
||||
EXPECT_EQ(count, 5u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(arr_vec3_i32, &count), vec3_i32);
|
||||
EXPECT_EQ(count, 5u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(arr_mat4x3_f16, &count), mat4x3_f16);
|
||||
EXPECT_EQ(count, 5u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(arr_mat4x3_af, &count), mat4x3_af);
|
||||
EXPECT_EQ(count, 5u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::ElementOf(arr_str_f16, &count), str_f16);
|
||||
EXPECT_EQ(count, 5u);
|
||||
}
|
||||
|
||||
TEST_F(TypeTest, DeepestElementOf) {
|
||||
// No count
|
||||
EXPECT_TYPE(Type::DeepestElementOf(f32), f32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(f16), f16);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(i32), i32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(u32), u32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(vec2_f32), f32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(vec3_f16), f16);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(vec4_f32), f32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(vec3_u32), u32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(vec3_i32), i32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(mat2x4_f32), f32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(mat4x2_f32), f32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(mat4x3_f16), f16);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(str_f16), str_f16);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(arr_i32), i32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(arr_vec3_i32), i32);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_f16), f16);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_af), af);
|
||||
EXPECT_TYPE(Type::DeepestElementOf(arr_str_f16), str_f16);
|
||||
|
||||
// With count
|
||||
uint32_t count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(f32, &count), f32);
|
||||
EXPECT_EQ(count, 1u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(f16, &count), f16);
|
||||
EXPECT_EQ(count, 1u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(i32, &count), i32);
|
||||
EXPECT_EQ(count, 1u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(u32, &count), u32);
|
||||
EXPECT_EQ(count, 1u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(vec2_f32, &count), f32);
|
||||
EXPECT_EQ(count, 2u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(vec3_f16, &count), f16);
|
||||
EXPECT_EQ(count, 3u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(vec4_f32, &count), f32);
|
||||
EXPECT_EQ(count, 4u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(vec3_u32, &count), u32);
|
||||
EXPECT_EQ(count, 3u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(vec3_i32, &count), i32);
|
||||
EXPECT_EQ(count, 3u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(mat2x4_f32, &count), f32);
|
||||
EXPECT_EQ(count, 8u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(mat4x2_f32, &count), f32);
|
||||
EXPECT_EQ(count, 8u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(mat4x3_f16, &count), f16);
|
||||
EXPECT_EQ(count, 12u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(str_f16, &count), str_f16);
|
||||
EXPECT_EQ(count, 1u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(arr_i32, &count), i32);
|
||||
EXPECT_EQ(count, 5u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(arr_vec3_i32, &count), i32);
|
||||
EXPECT_EQ(count, 15u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_f16, &count), f16);
|
||||
EXPECT_EQ(count, 60u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_af, &count), af);
|
||||
EXPECT_EQ(count, 60u);
|
||||
count = 42;
|
||||
EXPECT_TYPE(Type::DeepestElementOf(arr_str_f16, &count), str_f16);
|
||||
EXPECT_EQ(count, 5u);
|
||||
}
|
||||
|
||||
TEST_F(TypeTest, Common2) {
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, ai}), ai);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, af}), af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f32, f32}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f16, f16}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{i32, i32}), i32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{u32, u32}), u32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{i32, u32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{u32, f32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f32, f16}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f16, i32}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, af}), af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, f32}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, f16}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, i32}), i32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, u32}), u32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, ai}), af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f32, ai}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f16, ai}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{i32, ai}), i32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{u32, ai}), u32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, af}), af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f32, af}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f16, af}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{i32, af}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{u32, af}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, ai}), af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, f32}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, f16}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, i32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, u32}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_ai}), vec3_ai);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_af}), vec3_af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_f32}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_f16}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec4_f32}), vec4_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_u32}), vec3_u32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_i32}), vec3_i32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f32}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f16}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec4_f32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_u32}), vec3_u32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_i32}), vec3_i32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_ai}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_ai}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_ai}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_ai}), vec3_u32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_ai}), vec3_i32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f32}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f16}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec4_f32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_u32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_i32}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_af}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_af}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_af}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_af}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_af}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_af}), mat4x3_af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat3x4_f32}), mat3x4_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_f32}), mat4x3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_f16}), mat4x3_f16);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat3x4_f32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f32}), mat4x3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f16}), mat4x3_f16);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat4x3_af}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_af}), mat4x3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_af}), mat4x3_f16);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f32, arr_mat4x3_f16}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f32, arr_mat4x3_af}), arr_mat4x3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f16, arr_mat4x3_af}), arr_mat4x3_f16);
|
||||
}
|
||||
|
||||
TEST_F(TypeTest, Common3) {
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, ai, ai}), ai);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, af, af}), af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f32, f32, f32}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f16, f16, f16}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{i32, i32, i32}), i32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{u32, u32, u32}), u32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, ai}), af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, f32, ai}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, f16, ai}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, i32, ai}), i32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, u32, ai}), u32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, ai, af}), af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f32, ai, f32}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f16, ai, f16}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{i32, ai, i32}), i32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{u32, ai, u32}), u32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, f32, ai}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, f16, ai}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, i32, ai}), i32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, u32, ai}), u32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f32, ai, f32}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f16, ai, f16}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{i32, ai, i32}), i32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{u32, ai, u32}), u32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, f32, af}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, f16, af}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, i32, af}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{af, u32, af}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f32, af, f32}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{f16, af, f16}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{i32, af, i32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{u32, af, u32}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, f32}), f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, f16}), f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, i32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, u32}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_ai, vec3_ai}), vec3_ai);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_af, vec3_af}), vec3_af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_f32, vec3_f32}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_f16, vec3_f16}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec4_f32, vec4_f32}), vec4_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_u32, vec3_u32}), vec3_u32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_i32, vec3_i32}), vec3_i32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_ai, vec3_f32}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_ai, vec3_f16}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_ai, vec4_f32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_ai, vec3_u32}), vec3_u32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_ai, vec3_i32}), vec3_i32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f32, vec3_ai}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_f16, vec3_ai}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec4_f32, vec3_ai}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_u32, vec3_ai}), vec3_u32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_i32, vec3_ai}), vec3_i32);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_af, vec3_f32}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f16, vec3_af, vec3_f16}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec4_f32, vec3_af, vec4_f32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_af, vec3_u32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_af, vec3_i32}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f32, vec3_af}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_f16, vec3_af}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec4_f32, vec3_af}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_u32, vec3_af}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_i32, vec3_af}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_f32}), vec3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_f16}), vec3_f16);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec4_f32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_u32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_i32}), nullptr);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_af, mat4x3_af}), mat4x3_af);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat3x4_f32, mat3x4_f32}), mat3x4_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_f32, mat4x3_f32}), mat4x3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_f16, mat4x3_f16}), mat4x3_f16);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat4x3_af, mat3x4_f32}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_af, mat4x3_f32}), mat4x3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_af, mat4x3_f16}), mat4x3_f16);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat3x4_f32, mat4x3_af}), nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f32, mat4x3_af}), mat4x3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f16, mat4x3_af}), mat4x3_f16);
|
||||
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f16, arr_mat4x3_f32, arr_mat4x3_f16}),
|
||||
nullptr);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_af, arr_mat4x3_f32, arr_mat4x3_af}),
|
||||
arr_mat4x3_f32);
|
||||
EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_af, arr_mat4x3_f16, arr_mat4x3_af}),
|
||||
arr_mat4x3_f16);
|
||||
}
|
||||
|
||||
TEST_F(TypeTest, HoldsAbstract) {
|
||||
EXPECT_TRUE(af->HoldsAbstract());
|
||||
EXPECT_TRUE(ai->HoldsAbstract());
|
||||
EXPECT_FALSE(f32->HoldsAbstract());
|
||||
EXPECT_FALSE(f16->HoldsAbstract());
|
||||
EXPECT_FALSE(i32->HoldsAbstract());
|
||||
EXPECT_FALSE(u32->HoldsAbstract());
|
||||
EXPECT_FALSE(vec2_f32->HoldsAbstract());
|
||||
EXPECT_FALSE(vec3_f32->HoldsAbstract());
|
||||
EXPECT_FALSE(vec3_f16->HoldsAbstract());
|
||||
EXPECT_FALSE(vec4_f32->HoldsAbstract());
|
||||
EXPECT_FALSE(vec3_u32->HoldsAbstract());
|
||||
EXPECT_FALSE(vec3_i32->HoldsAbstract());
|
||||
EXPECT_TRUE(vec3_af->HoldsAbstract());
|
||||
EXPECT_TRUE(vec3_ai->HoldsAbstract());
|
||||
EXPECT_FALSE(mat2x4_f32->HoldsAbstract());
|
||||
EXPECT_FALSE(mat3x4_f32->HoldsAbstract());
|
||||
EXPECT_FALSE(mat4x2_f32->HoldsAbstract());
|
||||
EXPECT_FALSE(mat4x3_f32->HoldsAbstract());
|
||||
EXPECT_FALSE(mat4x3_f16->HoldsAbstract());
|
||||
EXPECT_TRUE(mat4x3_af->HoldsAbstract());
|
||||
EXPECT_FALSE(str_f16->HoldsAbstract());
|
||||
EXPECT_TRUE(str_af->HoldsAbstract());
|
||||
EXPECT_FALSE(arr_i32->HoldsAbstract());
|
||||
EXPECT_TRUE(arr_ai->HoldsAbstract());
|
||||
EXPECT_FALSE(arr_vec3_i32->HoldsAbstract());
|
||||
EXPECT_TRUE(arr_vec3_ai->HoldsAbstract());
|
||||
EXPECT_FALSE(arr_mat4x3_f16->HoldsAbstract());
|
||||
EXPECT_FALSE(arr_mat4x3_f32->HoldsAbstract());
|
||||
EXPECT_TRUE(arr_mat4x3_af->HoldsAbstract());
|
||||
EXPECT_FALSE(arr_str_f16->HoldsAbstract());
|
||||
EXPECT_TRUE(arr_str_af->HoldsAbstract());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::type
|
||||
Reference in New Issue
Block a user