Expose interpolation and dimensional data about IO variables
BUG=tint:859 Change-Id: I12da0fa49d7384bc321d27e84bad76b23081a56e Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/56623 Auto-Submit: Ryan Harrison <rharrison@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ryan Harrison <rharrison@chromium.org> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
62c8f2a9d6
commit
d4c64af117
|
@ -22,5 +22,35 @@ EntryPoint::EntryPoint(EntryPoint&) = default;
|
|||
EntryPoint::EntryPoint(EntryPoint&&) = default;
|
||||
EntryPoint::~EntryPoint() = default;
|
||||
|
||||
InterpolationType ASTToInspectorInterpolationType(
|
||||
ast::InterpolationType ast_type) {
|
||||
switch (ast_type) {
|
||||
case ast::InterpolationType::kPerspective:
|
||||
return InterpolationType::kPerspective;
|
||||
case ast::InterpolationType::kLinear:
|
||||
return InterpolationType::kLinear;
|
||||
case ast::InterpolationType::kFlat:
|
||||
return InterpolationType::kFlat;
|
||||
}
|
||||
|
||||
return InterpolationType::kUnknown;
|
||||
}
|
||||
|
||||
InterpolationSampling ASTToInspectorInterpolationSampling(
|
||||
ast::InterpolationSampling sampling) {
|
||||
switch (sampling) {
|
||||
case ast::InterpolationSampling::kNone:
|
||||
return InterpolationSampling::kNone;
|
||||
case ast::InterpolationSampling::kCenter:
|
||||
return InterpolationSampling::kCenter;
|
||||
case ast::InterpolationSampling::kCentroid:
|
||||
return InterpolationSampling::kCentroid;
|
||||
case ast::InterpolationSampling::kSample:
|
||||
return InterpolationSampling::kSample;
|
||||
}
|
||||
|
||||
return InterpolationSampling::kUnknown;
|
||||
}
|
||||
|
||||
} // namespace inspector
|
||||
} // namespace tint
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "src/ast/interpolate_decoration.h"
|
||||
#include "src/ast/pipeline_stage.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -32,19 +33,60 @@ enum class ComponentType {
|
|||
kSInt,
|
||||
};
|
||||
|
||||
/// Composition of components of a stage variable.
|
||||
enum class CompositionType {
|
||||
kUnknown = -1,
|
||||
kScalar,
|
||||
kVec2,
|
||||
kVec3,
|
||||
kVec4,
|
||||
};
|
||||
|
||||
/// Type of interpolation of a stage variable.
|
||||
enum class InterpolationType { kUnknown = -1, kPerspective, kLinear, kFlat };
|
||||
|
||||
/// Type of interpolation sampling of a stage variable.
|
||||
enum class InterpolationSampling {
|
||||
kUnknown = -1,
|
||||
kNone,
|
||||
kCenter,
|
||||
kCentroid,
|
||||
kSample
|
||||
};
|
||||
|
||||
/// Reflection data about an entry point input or output.
|
||||
struct StageVariable {
|
||||
/// Name of the variable in the shader.
|
||||
std::string name;
|
||||
/// Is Location Decoration present
|
||||
bool has_location_decoration;
|
||||
bool has_location_decoration = false;
|
||||
/// Value of Location Decoration, only valid if |has_location_decoration| is
|
||||
/// true.
|
||||
uint32_t location_decoration;
|
||||
/// Scalar type that the variable is composed of.
|
||||
ComponentType component_type;
|
||||
ComponentType component_type = ComponentType::kUnknown;
|
||||
/// How the scalars are composed for the variable.
|
||||
CompositionType composition_type = CompositionType::kUnknown;
|
||||
/// Interpolation type of the variable.
|
||||
InterpolationType interpolation_type = InterpolationType::kUnknown;
|
||||
/// Interpolation sampling of the variable.
|
||||
InterpolationSampling interpolation_sampling =
|
||||
InterpolationSampling::kUnknown;
|
||||
};
|
||||
|
||||
/// Convert from internal ast::InterpolationType to public ::InterpolationType.
|
||||
/// @param ast_type internal value to convert from
|
||||
/// @returns the publicly visible equivalent
|
||||
InterpolationType ASTToInspectorInterpolationType(
|
||||
ast::InterpolationType ast_type);
|
||||
|
||||
/// Convert from internal ast::InterpolationSampling to public
|
||||
/// ::InterpolationSampling
|
||||
/// @param sampling internal value to convert from
|
||||
/// @returns the publicly visible equivalent
|
||||
InterpolationSampling ASTToInspectorInterpolationSampling(
|
||||
ast::InterpolationSampling sampling);
|
||||
|
||||
/// Reflection data about a pipeline overridable constant referenced by an entry
|
||||
/// point
|
||||
struct OverridableConstant {
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "src/ast/bool_literal.h"
|
||||
#include "src/ast/call_expression.h"
|
||||
#include "src/ast/float_literal.h"
|
||||
#include "src/ast/interpolate_decoration.h"
|
||||
#include "src/ast/location_decoration.h"
|
||||
#include "src/ast/module.h"
|
||||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/scalar_constructor_expression.h"
|
||||
|
@ -56,6 +58,68 @@ void AppendResourceBindings(std::vector<ResourceBinding>* dest,
|
|||
dest->insert(dest->end(), orig.begin(), orig.end());
|
||||
}
|
||||
|
||||
std::tuple<ComponentType, CompositionType> CalculateComponentAndComposition(
|
||||
const sem::Type* type) {
|
||||
if (type->is_float_scalar()) {
|
||||
return {ComponentType::kFloat, CompositionType::kScalar};
|
||||
} else if (type->is_float_vector()) {
|
||||
auto* vec = type->As<sem::Vector>();
|
||||
if (vec->size() == 2) {
|
||||
return {ComponentType::kFloat, CompositionType::kVec2};
|
||||
} else if (vec->size() == 3) {
|
||||
return {ComponentType::kFloat, CompositionType::kVec3};
|
||||
} else if (vec->size() == 4) {
|
||||
return {ComponentType::kFloat, CompositionType::kVec4};
|
||||
}
|
||||
} else if (type->is_unsigned_integer_scalar()) {
|
||||
return {ComponentType::kUInt, CompositionType::kScalar};
|
||||
} else if (type->is_unsigned_integer_vector()) {
|
||||
auto* vec = type->As<sem::Vector>();
|
||||
if (vec->size() == 2) {
|
||||
return {ComponentType::kUInt, CompositionType::kVec2};
|
||||
} else if (vec->size() == 3) {
|
||||
return {ComponentType::kUInt, CompositionType::kVec3};
|
||||
} else if (vec->size() == 4) {
|
||||
return {ComponentType::kUInt, CompositionType::kVec4};
|
||||
}
|
||||
} else if (type->is_signed_integer_scalar()) {
|
||||
return {ComponentType::kSInt, CompositionType::kScalar};
|
||||
} else if (type->is_signed_integer_vector()) {
|
||||
auto* vec = type->As<sem::Vector>();
|
||||
if (vec->size() == 2) {
|
||||
return {ComponentType::kSInt, CompositionType::kVec2};
|
||||
} else if (vec->size() == 3) {
|
||||
return {ComponentType::kSInt, CompositionType::kVec3};
|
||||
} else if (vec->size() == 4) {
|
||||
return {ComponentType::kSInt, CompositionType::kVec4};
|
||||
}
|
||||
}
|
||||
return {ComponentType::kUnknown, CompositionType::kUnknown};
|
||||
}
|
||||
|
||||
std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData(
|
||||
const sem::Type* type,
|
||||
const ast::DecorationList& decorations) {
|
||||
auto* interpolation_decoration =
|
||||
ast::GetDecoration<ast::InterpolateDecoration>(decorations);
|
||||
if (type->is_integer_scalar_or_vector()) {
|
||||
return {InterpolationType::kFlat, InterpolationSampling::kNone};
|
||||
}
|
||||
|
||||
if (!interpolation_decoration) {
|
||||
return {InterpolationType::kPerspective, InterpolationSampling::kCenter};
|
||||
}
|
||||
|
||||
auto interpolation_type = interpolation_decoration->type();
|
||||
auto sampling = interpolation_decoration->sampling();
|
||||
if (interpolation_type != ast::InterpolationType::kFlat &&
|
||||
sampling == ast::InterpolationSampling::kNone) {
|
||||
sampling = ast::InterpolationSampling::kCenter;
|
||||
}
|
||||
return {ASTToInspectorInterpolationType(interpolation_type),
|
||||
ASTToInspectorInterpolationSampling(sampling)};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Inspector::Inspector(const Program* program) : program_(program) {}
|
||||
|
@ -116,15 +180,10 @@ std::vector<EntryPoint> Inspector::GetEntryPoints() {
|
|||
StageVariable stage_variable;
|
||||
stage_variable.name = name;
|
||||
|
||||
stage_variable.component_type = ComponentType::kUnknown;
|
||||
auto* type = var->Type()->UnwrapRef();
|
||||
if (type->is_float_scalar_or_vector() || type->is_float_matrix()) {
|
||||
stage_variable.component_type = ComponentType::kFloat;
|
||||
} else if (type->is_unsigned_scalar_or_vector()) {
|
||||
stage_variable.component_type = ComponentType::kUInt;
|
||||
} else if (type->is_signed_scalar_or_vector()) {
|
||||
stage_variable.component_type = ComponentType::kSInt;
|
||||
}
|
||||
std::tie(stage_variable.component_type,
|
||||
stage_variable.composition_type) =
|
||||
CalculateComponentAndComposition(type);
|
||||
|
||||
auto* location_decoration =
|
||||
ast::GetDecoration<ast::LocationDecoration>(decl->decorations());
|
||||
|
@ -135,6 +194,10 @@ std::vector<EntryPoint> Inspector::GetEntryPoints() {
|
|||
stage_variable.has_location_decoration = false;
|
||||
}
|
||||
|
||||
std::tie(stage_variable.interpolation_type,
|
||||
stage_variable.interpolation_sampling) =
|
||||
CalculateInterpolationData(type, decl->decorations());
|
||||
|
||||
if (var->StorageClass() == ast::StorageClass::kInput) {
|
||||
entry_point.input_variables.push_back(stage_variable);
|
||||
} else if (var->StorageClass() == ast::StorageClass::kOutput) {
|
||||
|
@ -520,21 +583,18 @@ void Inspector::AddEntryPointInOutVariables(
|
|||
|
||||
StageVariable stage_variable;
|
||||
stage_variable.name = name;
|
||||
stage_variable.component_type = ComponentType::kUnknown;
|
||||
if (unwrapped_type->is_float_scalar_or_vector() ||
|
||||
unwrapped_type->is_float_matrix()) {
|
||||
stage_variable.component_type = ComponentType::kFloat;
|
||||
} else if (unwrapped_type->is_unsigned_scalar_or_vector()) {
|
||||
stage_variable.component_type = ComponentType::kUInt;
|
||||
} else if (unwrapped_type->is_signed_scalar_or_vector()) {
|
||||
stage_variable.component_type = ComponentType::kSInt;
|
||||
}
|
||||
std::tie(stage_variable.component_type, stage_variable.composition_type) =
|
||||
CalculateComponentAndComposition(type);
|
||||
|
||||
auto* location = ast::GetDecoration<ast::LocationDecoration>(decorations);
|
||||
TINT_ASSERT(Inspector, location != nullptr);
|
||||
stage_variable.has_location_decoration = true;
|
||||
stage_variable.location_decoration = location->value();
|
||||
|
||||
std::tie(stage_variable.interpolation_type,
|
||||
stage_variable.interpolation_sampling) =
|
||||
CalculateInterpolationData(type, decorations);
|
||||
|
||||
variables.push_back(stage_variable);
|
||||
}
|
||||
|
||||
|
|
|
@ -639,6 +639,43 @@ class InspectorHelper : public ProgramBuilder {
|
|||
return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations);
|
||||
}
|
||||
|
||||
std::function<ast::Type*()> GetTypeFunction(ComponentType component,
|
||||
CompositionType composition) {
|
||||
std::function<ast::Type*()> func;
|
||||
switch (component) {
|
||||
case ComponentType::kFloat:
|
||||
func = [this]() -> ast::Type* { return ty.f32(); };
|
||||
break;
|
||||
case ComponentType::kSInt:
|
||||
func = [this]() -> ast::Type* { return ty.i32(); };
|
||||
break;
|
||||
case ComponentType::kUInt:
|
||||
func = [this]() -> ast::Type* { return ty.u32(); };
|
||||
break;
|
||||
case ComponentType::kUnknown:
|
||||
return []() -> ast::Type* { return nullptr; };
|
||||
}
|
||||
|
||||
uint32_t n;
|
||||
switch (composition) {
|
||||
case CompositionType::kScalar:
|
||||
return func;
|
||||
case CompositionType::kVec2:
|
||||
n = 2;
|
||||
break;
|
||||
case CompositionType::kVec3:
|
||||
n = 3;
|
||||
break;
|
||||
case CompositionType::kVec4:
|
||||
n = 4;
|
||||
break;
|
||||
default:
|
||||
return []() -> ast::Type* { return nullptr; };
|
||||
}
|
||||
|
||||
return [this, func, n]() -> ast::Type* { return ty.vec(func(), n); };
|
||||
}
|
||||
|
||||
Inspector& Build() {
|
||||
if (inspector_) {
|
||||
return *inspector_;
|
||||
|
@ -666,9 +703,23 @@ class InspectorHelper : public ProgramBuilder {
|
|||
|
||||
class InspectorGetEntryPointTest : public InspectorHelper,
|
||||
public testing::Test {};
|
||||
class InspectorGetEntryPointTestWithComponentTypeParam
|
||||
|
||||
typedef std::tuple<inspector::ComponentType, inspector::CompositionType>
|
||||
InspectorGetEntryPointComponentAndCompositionTestParams;
|
||||
class InspectorGetEntryPointComponentAndCompositionTest
|
||||
: public InspectorHelper,
|
||||
public testing::TestWithParam<ComponentType> {};
|
||||
public testing::TestWithParam<
|
||||
InspectorGetEntryPointComponentAndCompositionTestParams> {};
|
||||
struct InspectorGetEntryPointInterpolateTestParams {
|
||||
ast::InterpolationType in_type;
|
||||
ast::InterpolationSampling in_sampling;
|
||||
inspector::InterpolationType out_type;
|
||||
inspector::InterpolationSampling out_sampling;
|
||||
};
|
||||
class InspectorGetEntryPointInterpolateTest
|
||||
: public InspectorHelper,
|
||||
public testing::TestWithParam<
|
||||
InspectorGetEntryPointInterpolateTestParams> {};
|
||||
class InspectorGetRemappedNameForEntryPointTest : public InspectorHelper,
|
||||
public testing::Test {};
|
||||
class InspectorGetConstantIDsTest : public InspectorHelper,
|
||||
|
@ -889,22 +940,12 @@ TEST_F(InspectorGetEntryPointTest, NoInOutVariables) {
|
|||
EXPECT_EQ(0u, result[0].output_variables.size());
|
||||
}
|
||||
|
||||
TEST_P(InspectorGetEntryPointTestWithComponentTypeParam, InOutVariables) {
|
||||
ComponentType inspector_type = GetParam();
|
||||
std::function<ast::Type*()> tint_type;
|
||||
switch (inspector_type) {
|
||||
case ComponentType::kFloat:
|
||||
tint_type = [this]() -> ast::Type* { return ty.f32(); };
|
||||
break;
|
||||
case ComponentType::kSInt:
|
||||
tint_type = [this]() -> ast::Type* { return ty.i32(); };
|
||||
break;
|
||||
case ComponentType::kUInt:
|
||||
tint_type = [this]() -> ast::Type* { return ty.u32(); };
|
||||
break;
|
||||
case ComponentType::kUnknown:
|
||||
return;
|
||||
}
|
||||
TEST_P(InspectorGetEntryPointComponentAndCompositionTest, Test) {
|
||||
ComponentType component;
|
||||
CompositionType composition;
|
||||
std::tie(component, composition) = GetParam();
|
||||
std::function<ast::Type*()> tint_type =
|
||||
GetTypeFunction(component, composition);
|
||||
|
||||
auto* in_var = Param("in_var", tint_type(), {Location(0u)});
|
||||
Func("foo", {in_var}, tint_type(), {Return("in_var")},
|
||||
|
@ -920,19 +961,24 @@ TEST_P(InspectorGetEntryPointTestWithComponentTypeParam, InOutVariables) {
|
|||
EXPECT_EQ("in_var", result[0].input_variables[0].name);
|
||||
EXPECT_TRUE(result[0].input_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].input_variables[0].location_decoration);
|
||||
EXPECT_EQ(inspector_type, result[0].input_variables[0].component_type);
|
||||
EXPECT_EQ(component, result[0].input_variables[0].component_type);
|
||||
|
||||
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||
EXPECT_EQ("<retval>", result[0].output_variables[0].name);
|
||||
EXPECT_TRUE(result[0].output_variables[0].has_location_decoration);
|
||||
EXPECT_EQ(0u, result[0].output_variables[0].location_decoration);
|
||||
EXPECT_EQ(inspector_type, result[0].output_variables[0].component_type);
|
||||
EXPECT_EQ(component, result[0].output_variables[0].component_type);
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(InspectorGetEntryPointTest,
|
||||
InspectorGetEntryPointTestWithComponentTypeParam,
|
||||
testing::Values(ComponentType::kFloat,
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
InspectorGetEntryPointTest,
|
||||
InspectorGetEntryPointComponentAndCompositionTest,
|
||||
testing::Combine(testing::Values(ComponentType::kFloat,
|
||||
ComponentType::kSInt,
|
||||
ComponentType::kUInt));
|
||||
ComponentType::kUInt),
|
||||
testing::Values(CompositionType::kScalar,
|
||||
CompositionType::kVec2,
|
||||
CompositionType::kVec3,
|
||||
CompositionType::kVec4)));
|
||||
|
||||
TEST_F(InspectorGetEntryPointTest, MultipleInOutVariables) {
|
||||
auto* in_var0 = Param("in_var0", ty.u32(), {Location(0u)});
|
||||
|
@ -1603,6 +1649,89 @@ TEST_F(InspectorGetEntryPointTest, SampleMaskStructReferenced) {
|
|||
EXPECT_TRUE(result[0].sample_mask_used);
|
||||
}
|
||||
|
||||
TEST_F(InspectorGetEntryPointTest, ImplicitInterpolate) {
|
||||
ast::StructMemberList members;
|
||||
members.push_back(Member("struct_inner", ty.f32(), {Location(0)}));
|
||||
Structure("in_struct", members, {});
|
||||
auto* in_var = Param("in_var", ty.type_name("in_struct"), {});
|
||||
|
||||
Func("ep_func", {in_var}, ty.void_(), {Return()},
|
||||
{Stage(ast::PipelineStage::kFragment)}, {});
|
||||
|
||||
Inspector& inspector = Build();
|
||||
|
||||
auto result = inspector.GetEntryPoints();
|
||||
|
||||
ASSERT_EQ(1u, result.size());
|
||||
ASSERT_EQ(1u, result[0].input_variables.size());
|
||||
EXPECT_EQ(InterpolationType::kPerspective,
|
||||
result[0].input_variables[0].interpolation_type);
|
||||
EXPECT_EQ(InterpolationSampling::kCenter,
|
||||
result[0].input_variables[0].interpolation_sampling);
|
||||
}
|
||||
|
||||
TEST_P(InspectorGetEntryPointInterpolateTest, Test) {
|
||||
auto& params = GetParam();
|
||||
ast::StructMemberList members;
|
||||
members.push_back(
|
||||
Member("struct_inner", ty.f32(),
|
||||
{Interpolate(params.in_type, params.in_sampling), Location(0)}));
|
||||
Structure("in_struct", members, {});
|
||||
auto* in_var = Param("in_var", ty.type_name("in_struct"), {});
|
||||
|
||||
Func("ep_func", {in_var}, ty.void_(), {Return()},
|
||||
{Stage(ast::PipelineStage::kFragment)}, {});
|
||||
|
||||
Inspector& inspector = Build();
|
||||
|
||||
auto result = inspector.GetEntryPoints();
|
||||
|
||||
ASSERT_EQ(1u, result.size());
|
||||
ASSERT_EQ(1u, result[0].input_variables.size());
|
||||
EXPECT_EQ(params.out_type, result[0].input_variables[0].interpolation_type);
|
||||
EXPECT_EQ(params.out_sampling,
|
||||
result[0].input_variables[0].interpolation_sampling);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
InspectorGetEntryPointTest,
|
||||
InspectorGetEntryPointInterpolateTest,
|
||||
testing::Values(
|
||||
InspectorGetEntryPointInterpolateTestParams{
|
||||
ast::InterpolationType::kPerspective,
|
||||
ast::InterpolationSampling::kCenter,
|
||||
InterpolationType::kPerspective, InterpolationSampling::kCenter},
|
||||
InspectorGetEntryPointInterpolateTestParams{
|
||||
ast::InterpolationType::kPerspective,
|
||||
ast::InterpolationSampling::kCentroid,
|
||||
InterpolationType::kPerspective, InterpolationSampling::kCentroid},
|
||||
InspectorGetEntryPointInterpolateTestParams{
|
||||
ast::InterpolationType::kPerspective,
|
||||
ast::InterpolationSampling::kSample,
|
||||
InterpolationType::kPerspective, InterpolationSampling::kSample},
|
||||
InspectorGetEntryPointInterpolateTestParams{
|
||||
ast::InterpolationType::kPerspective,
|
||||
ast::InterpolationSampling::kNone, InterpolationType::kPerspective,
|
||||
InterpolationSampling::kCenter},
|
||||
InspectorGetEntryPointInterpolateTestParams{
|
||||
ast::InterpolationType::kLinear,
|
||||
ast::InterpolationSampling::kCenter, InterpolationType::kLinear,
|
||||
InterpolationSampling::kCenter},
|
||||
InspectorGetEntryPointInterpolateTestParams{
|
||||
ast::InterpolationType::kLinear,
|
||||
ast::InterpolationSampling::kCentroid, InterpolationType::kLinear,
|
||||
InterpolationSampling::kCentroid},
|
||||
InspectorGetEntryPointInterpolateTestParams{
|
||||
ast::InterpolationType::kLinear,
|
||||
ast::InterpolationSampling::kSample, InterpolationType::kLinear,
|
||||
InterpolationSampling::kSample},
|
||||
InspectorGetEntryPointInterpolateTestParams{
|
||||
ast::InterpolationType::kLinear, ast::InterpolationSampling::kNone,
|
||||
InterpolationType::kLinear, InterpolationSampling::kCenter},
|
||||
InspectorGetEntryPointInterpolateTestParams{
|
||||
ast::InterpolationType::kFlat, ast::InterpolationSampling::kNone,
|
||||
InterpolationType::kFlat, InterpolationSampling::kNone}));
|
||||
|
||||
// TODO(rharrison): Reenable once GetRemappedNameForEntryPoint isn't a pass
|
||||
// through
|
||||
TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_NoFunctions) {
|
||||
|
|
|
@ -86,14 +86,22 @@ bool Type::is_integer_scalar() const {
|
|||
return IsAnyOf<U32, I32>();
|
||||
}
|
||||
|
||||
bool Type::is_unsigned_integer_vector() const {
|
||||
return Is<Vector>([](const Vector* v) { return v->type()->Is<U32>(); });
|
||||
bool Type::is_signed_integer_scalar() const {
|
||||
return Is<I32>();
|
||||
}
|
||||
|
||||
bool Type::is_unsigned_integer_scalar() const {
|
||||
return Is<U32>();
|
||||
}
|
||||
|
||||
bool Type::is_signed_integer_vector() const {
|
||||
return Is<Vector>([](const Vector* v) { return v->type()->Is<I32>(); });
|
||||
}
|
||||
|
||||
bool Type::is_unsigned_integer_vector() const {
|
||||
return Is<Vector>([](const Vector* v) { return v->type()->Is<U32>(); });
|
||||
}
|
||||
|
||||
bool Type::is_unsigned_scalar_or_vector() const {
|
||||
return Is<U32>() || is_unsigned_integer_vector();
|
||||
}
|
||||
|
|
|
@ -69,6 +69,10 @@ class Type : public Castable<Type, Node> {
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue