tint: Add sem::Type::ConversionRank()
Returns the implicit conversion rank as defined by: https://www.w3.org/TR/WGSL/#conversion-rank Bug: tint:1504 Change-Id: I17b17a1d3b4f0e5816a92ec0b86d364c288b59d8 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/90663 Reviewed-by: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@chromium.org>
This commit is contained in:
parent
5fbe4b65e6
commit
e0ff664a7f
|
@ -810,6 +810,7 @@ if(TINT_BUILD_TESTS)
|
|||
sem/sem_struct_test.cc
|
||||
sem/storage_texture_test.cc
|
||||
sem/texture_test.cc
|
||||
sem/type_test.cc
|
||||
sem/type_manager_test.cc
|
||||
sem/u32_test.cc
|
||||
sem/vector_test.cc
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "src/tint/sem/type.h"
|
||||
|
||||
#include "src/tint/sem/abstract_float.h"
|
||||
#include "src/tint/sem/abstract_int.h"
|
||||
#include "src/tint/sem/bool.h"
|
||||
#include "src/tint/sem/f16.h"
|
||||
#include "src/tint/sem/f32.h"
|
||||
|
@ -153,4 +155,47 @@ bool Type::is_handle() const {
|
|||
return IsAnyOf<Sampler, Texture>();
|
||||
}
|
||||
|
||||
uint32_t Type::ConversionRank(const Type* from, const Type* to) {
|
||||
if (from->UnwrapRef() == to) {
|
||||
return 0;
|
||||
}
|
||||
return Switch(
|
||||
from,
|
||||
[&](const AbstractFloat*) {
|
||||
return Switch(
|
||||
to, //
|
||||
[&](const F32*) { return 1; }, //
|
||||
[&](const F16*) { return 2; }, //
|
||||
[&](Default) { return kNoConversion; });
|
||||
},
|
||||
[&](const AbstractInt*) {
|
||||
return Switch(
|
||||
to, //
|
||||
[&](const I32*) { return 3; }, //
|
||||
[&](const U32*) { return 4; }, //
|
||||
[&](const AbstractFloat*) { return 5; }, //
|
||||
[&](const F32*) { return 6; }, //
|
||||
[&](const F16*) { return 7; }, //
|
||||
[&](Default) { return kNoConversion; });
|
||||
},
|
||||
[&](const Vector* from_vec) {
|
||||
if (auto* to_vec = to->As<Vector>()) {
|
||||
if (from_vec->Width() == to_vec->Width()) {
|
||||
return ConversionRank(from_vec->type(), to_vec->type());
|
||||
}
|
||||
}
|
||||
return kNoConversion;
|
||||
},
|
||||
[&](const Matrix* from_mat) {
|
||||
if (auto* to_mat = to->As<Matrix>()) {
|
||||
if (from_mat->columns() == to_mat->columns() &&
|
||||
from_mat->rows() == to_mat->rows()) {
|
||||
return ConversionRank(from_mat->type(), to_mat->type());
|
||||
}
|
||||
}
|
||||
return kNoConversion;
|
||||
},
|
||||
[&](Default) { return kNoConversion; });
|
||||
}
|
||||
|
||||
} // namespace tint::sem
|
||||
|
|
|
@ -114,6 +114,19 @@ class Type : public Castable<Type, Node> {
|
|||
/// @returns true if this type is a handle type
|
||||
bool is_handle() 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);
|
||||
|
||||
protected:
|
||||
Type();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
// 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/reference.h"
|
||||
#include "src/tint/sem/test_helper.h"
|
||||
|
||||
namespace tint::sem {
|
||||
namespace {
|
||||
|
||||
using TypeTest = TestHelper;
|
||||
|
||||
TEST_F(TypeTest, ConversionRank) {
|
||||
auto* af = create<AbstractFloat>();
|
||||
auto* ai = create<AbstractInt>();
|
||||
auto* f32 = create<F32>();
|
||||
auto* f16 = create<F16>();
|
||||
auto* i32 = create<I32>();
|
||||
auto* u32 = create<U32>();
|
||||
auto* vec3_f32 = create<Vector>(f32, 3u);
|
||||
auto* vec3_f16 = create<Vector>(f16, 3u);
|
||||
auto* vec4_f32 = create<Vector>(f32, 4u);
|
||||
auto* vec3_u32 = create<Vector>(u32, 3u);
|
||||
auto* vec3_i32 = create<Vector>(i32, 3u);
|
||||
auto* vec3_af = create<Vector>(af, 3u);
|
||||
auto* vec3_ai = create<Vector>(ai, 3u);
|
||||
auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
|
||||
auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
|
||||
auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
|
||||
auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
|
||||
auto* ref_u32 = create<Reference>(u32, ast::StorageClass::kPrivate, ast::Access::kReadWrite);
|
||||
|
||||
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(mat4x3_af, 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(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(ai, i32), 3u);
|
||||
EXPECT_EQ(Type::ConversionRank(vec3_ai, 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(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(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);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::sem
|
|
@ -303,6 +303,7 @@ tint_unittests_source_set("tint_unittests_sem_src") {
|
|||
"../../src/tint/sem/sem_struct_test.cc",
|
||||
"../../src/tint/sem/storage_texture_test.cc",
|
||||
"../../src/tint/sem/texture_test.cc",
|
||||
"../../src/tint/sem/type_test.cc",
|
||||
"../../src/tint/sem/type_manager_test.cc",
|
||||
"../../src/tint/sem/u32_test.cc",
|
||||
"../../src/tint/sem/vector_test.cc",
|
||||
|
|
Loading…
Reference in New Issue