spirv-writer: support identity cast for vectors
Pending WGSL spec update https://github.com/gpuweb/gpuweb/issues/1103 Bug: tint:352 Change-Id: Ice44066ffcbb64de2544f82489e07b19a2423f72 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/33601 Commit-Queue: David Neto <dneto@google.com> Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
4c13659a2a
commit
6cd6f7462c
|
@ -1224,7 +1224,7 @@ uint32_t Builder::GenerateTypeConstructorExpression(
|
||||||
result_type->AsVector()->size() == value_type->AsVector()->size());
|
result_type->AsVector()->size() == value_type->AsVector()->size());
|
||||||
}
|
}
|
||||||
if (can_cast_or_copy) {
|
if (can_cast_or_copy) {
|
||||||
return GenerateCastOrCopy(result_type, values[0]);
|
return GenerateCastOrCopyOrPassthrough(result_type, values[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto type_id = GenerateTypeIfNeeded(init->type());
|
auto type_id = GenerateTypeIfNeeded(init->type());
|
||||||
|
@ -1268,7 +1268,7 @@ uint32_t Builder::GenerateTypeConstructorExpression(
|
||||||
// Both scalars, but not the same type so we need to generate a conversion
|
// Both scalars, but not the same type so we need to generate a conversion
|
||||||
// of the value.
|
// of the value.
|
||||||
if (value_type->is_scalar() && result_type->is_scalar()) {
|
if (value_type->is_scalar() && result_type->is_scalar()) {
|
||||||
id = GenerateCastOrCopy(result_type, values[0]);
|
id = GenerateCastOrCopyOrPassthrough(result_type, values[0]);
|
||||||
out << "_" << id;
|
out << "_" << id;
|
||||||
ops.push_back(Operand::Int(id));
|
ops.push_back(Operand::Int(id));
|
||||||
continue;
|
continue;
|
||||||
|
@ -1351,8 +1351,8 @@ uint32_t Builder::GenerateTypeConstructorExpression(
|
||||||
return result.to_i();
|
return result.to_i();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Builder::GenerateCastOrCopy(ast::type::Type* to_type,
|
uint32_t Builder::GenerateCastOrCopyOrPassthrough(ast::type::Type* to_type,
|
||||||
ast::Expression* from_expr) {
|
ast::Expression* from_expr) {
|
||||||
auto result = result_op();
|
auto result = result_op();
|
||||||
auto result_id = result.to_i();
|
auto result_id = result.to_i();
|
||||||
|
|
||||||
|
@ -1388,8 +1388,9 @@ uint32_t Builder::GenerateCastOrCopy(ast::type::Type* to_type,
|
||||||
} else if ((from_type->IsBool() && to_type->IsBool()) ||
|
} else if ((from_type->IsBool() && to_type->IsBool()) ||
|
||||||
(from_type->IsU32() && to_type->IsU32()) ||
|
(from_type->IsU32() && to_type->IsU32()) ||
|
||||||
(from_type->IsI32() && to_type->IsI32()) ||
|
(from_type->IsI32() && to_type->IsI32()) ||
|
||||||
(from_type->IsF32() && to_type->IsF32())) {
|
(from_type->IsF32() && to_type->IsF32()) ||
|
||||||
op = spv::Op::OpCopyObject;
|
(from_type->IsVector() && (from_type == to_type))) {
|
||||||
|
return val_id;
|
||||||
} else if ((from_type->IsI32() && to_type->IsU32()) ||
|
} else if ((from_type->IsI32() && to_type->IsU32()) ||
|
||||||
(from_type->IsU32() && to_type->IsI32()) ||
|
(from_type->IsU32() && to_type->IsI32()) ||
|
||||||
(from_type->is_signed_integer_vector() &&
|
(from_type->is_signed_integer_vector() &&
|
||||||
|
|
|
@ -350,12 +350,14 @@ class Builder {
|
||||||
uint32_t GenerateSampledImage(ast::type::Type* texture_type,
|
uint32_t GenerateSampledImage(ast::type::Type* texture_type,
|
||||||
Operand texture_operand,
|
Operand texture_operand,
|
||||||
Operand sampler_operand);
|
Operand sampler_operand);
|
||||||
/// Generates a cast or object copy for the expression result
|
/// Generates a cast or object copy for the expression result,
|
||||||
|
/// or return the ID generated the expression if it is already
|
||||||
|
/// of the right type.
|
||||||
/// @param to_type the type we're casting too
|
/// @param to_type the type we're casting too
|
||||||
/// @param from_expr the expression to cast
|
/// @param from_expr the expression to cast
|
||||||
/// @returns the expression ID on success or 0 otherwise
|
/// @returns the expression ID on success or 0 otherwise
|
||||||
uint32_t GenerateCastOrCopy(ast::type::Type* to_type,
|
uint32_t GenerateCastOrCopyOrPassthrough(ast::type::Type* to_type,
|
||||||
ast::Expression* from_expr);
|
ast::Expression* from_expr);
|
||||||
/// Generates a loop statement
|
/// Generates a loop statement
|
||||||
/// @param stmt the statement to generate
|
/// @param stmt the statement to generate
|
||||||
/// @returns true on successful generation
|
/// @returns true on successful generation
|
||||||
|
|
|
@ -193,15 +193,13 @@ TEST_F(SpvBuilderConstructorTest, Type_Bool_With_Bool) {
|
||||||
|
|
||||||
b.push_function(Function{});
|
b.push_function(Function{});
|
||||||
|
|
||||||
EXPECT_EQ(b.GenerateExpression(&cast), 1u);
|
EXPECT_EQ(b.GenerateExpression(&cast), 3u);
|
||||||
ASSERT_FALSE(b.has_error()) << b.error();
|
ASSERT_FALSE(b.has_error()) << b.error();
|
||||||
|
|
||||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
|
||||||
%3 = OpConstantTrue %2
|
%3 = OpConstantTrue %2
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
|
||||||
R"(%1 = OpCopyObject %2 %3
|
|
||||||
)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SpvBuilderConstructorTest, Type_I32_With_I32) {
|
TEST_F(SpvBuilderConstructorTest, Type_I32_With_I32) {
|
||||||
|
@ -210,14 +208,12 @@ TEST_F(SpvBuilderConstructorTest, Type_I32_With_I32) {
|
||||||
ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
|
ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
|
||||||
|
|
||||||
b.push_function(Function{});
|
b.push_function(Function{});
|
||||||
EXPECT_EQ(b.GenerateExpression(&cast), 1u);
|
EXPECT_EQ(b.GenerateExpression(&cast), 3u);
|
||||||
|
|
||||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
|
||||||
%3 = OpConstant %2 2
|
%3 = OpConstant %2 2
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
|
||||||
R"(%1 = OpCopyObject %2 %3
|
|
||||||
)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SpvBuilderConstructorTest, Type_U32_With_U32) {
|
TEST_F(SpvBuilderConstructorTest, Type_U32_With_U32) {
|
||||||
|
@ -226,14 +222,12 @@ TEST_F(SpvBuilderConstructorTest, Type_U32_With_U32) {
|
||||||
ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
|
ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
|
||||||
|
|
||||||
b.push_function(Function{});
|
b.push_function(Function{});
|
||||||
EXPECT_EQ(b.GenerateExpression(&cast), 1u);
|
EXPECT_EQ(b.GenerateExpression(&cast), 3u);
|
||||||
|
|
||||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
|
||||||
%3 = OpConstant %2 2
|
%3 = OpConstant %2 2
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
|
||||||
R"(%1 = OpCopyObject %2 %3
|
|
||||||
)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SpvBuilderConstructorTest, Type_F32_With_F32) {
|
TEST_F(SpvBuilderConstructorTest, Type_F32_With_F32) {
|
||||||
|
@ -242,14 +236,12 @@ TEST_F(SpvBuilderConstructorTest, Type_F32_With_F32) {
|
||||||
ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
|
ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
|
||||||
|
|
||||||
b.push_function(Function{});
|
b.push_function(Function{});
|
||||||
EXPECT_EQ(b.GenerateExpression(&cast), 1u);
|
EXPECT_EQ(b.GenerateExpression(&cast), 3u);
|
||||||
|
|
||||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
|
||||||
%3 = OpConstant %2 2
|
%3 = OpConstant %2 2
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
|
||||||
R"(%1 = OpCopyObject %2 %3
|
|
||||||
)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F32_F32) {
|
TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F32_F32) {
|
||||||
|
@ -267,6 +259,23 @@ TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F32_F32) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_Vec2) {
|
||||||
|
auto* value = vec2<f32>(2.0f, 2.0f);
|
||||||
|
auto* cast = vec2<f32>(value);
|
||||||
|
|
||||||
|
ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
|
||||||
|
|
||||||
|
b.push_function(Function{});
|
||||||
|
EXPECT_EQ(b.GenerateExpression(cast), 5u);
|
||||||
|
|
||||||
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||||
|
%2 = OpTypeVector %3 2
|
||||||
|
%4 = OpConstant %3 2
|
||||||
|
%5 = OpConstantComposite %2 %4 %4
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32_F32_F32) {
|
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32_F32_F32) {
|
||||||
auto* cast = vec3<f32>(2.0f, 2.0f, 2.0f);
|
auto* cast = vec3<f32>(2.0f, 2.0f, 2.0f);
|
||||||
|
|
||||||
|
@ -324,6 +333,23 @@ TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Vec2_F32) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Vec3) {
|
||||||
|
auto* value = vec3<f32>(2.0f, 2.0f, 2.0f);
|
||||||
|
auto* cast = vec3<f32>(value);
|
||||||
|
|
||||||
|
ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
|
||||||
|
|
||||||
|
b.push_function(Function{});
|
||||||
|
EXPECT_EQ(b.GenerateExpression(cast), 5u);
|
||||||
|
|
||||||
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||||
|
%2 = OpTypeVector %3 3
|
||||||
|
%4 = OpConstant %3 2
|
||||||
|
%5 = OpConstantComposite %2 %4 %4 %4
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_F32_F32_F32) {
|
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_F32_F32_F32) {
|
||||||
auto* cast = vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f);
|
auto* cast = vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f);
|
||||||
|
|
||||||
|
@ -469,6 +495,68 @@ TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec3_F32) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec4) {
|
||||||
|
auto* value = vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f);
|
||||||
|
auto* cast = vec4<f32>(value);
|
||||||
|
|
||||||
|
ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
|
||||||
|
|
||||||
|
b.push_function(Function{});
|
||||||
|
EXPECT_EQ(b.GenerateExpression(cast), 5u);
|
||||||
|
|
||||||
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||||
|
%2 = OpTypeVector %3 4
|
||||||
|
%4 = OpConstant %3 2
|
||||||
|
%5 = OpConstantComposite %2 %4 %4 %4 %4
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec2_With_Vec2) {
|
||||||
|
auto* cast = vec2<f32>(vec2<f32>(2.0f, 2.0f));
|
||||||
|
|
||||||
|
ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
|
||||||
|
|
||||||
|
b.push_function(Function{});
|
||||||
|
EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 5u);
|
||||||
|
|
||||||
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||||
|
%2 = OpTypeVector %3 2
|
||||||
|
%4 = OpConstant %3 2
|
||||||
|
%5 = OpConstantComposite %2 %4 %4
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_Vec3) {
|
||||||
|
auto* cast = vec3<f32>(vec3<f32>(2.0f, 2.0f, 2.0f));
|
||||||
|
|
||||||
|
ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
|
||||||
|
|
||||||
|
b.push_function(Function{});
|
||||||
|
EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 5u);
|
||||||
|
|
||||||
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||||
|
%2 = OpTypeVector %3 3
|
||||||
|
%4 = OpConstant %3 2
|
||||||
|
%5 = OpConstantComposite %2 %4 %4 %4
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec4) {
|
||||||
|
auto* cast = vec4<f32>(vec4<f32>(2.0f, 2.0f, 2.0f, 2.0f));
|
||||||
|
|
||||||
|
ASSERT_TRUE(td.DetermineResultType(cast)) << td.error();
|
||||||
|
|
||||||
|
b.push_function(Function{});
|
||||||
|
EXPECT_EQ(b.GenerateConstructorExpression(nullptr, cast, true), 5u);
|
||||||
|
|
||||||
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||||
|
%2 = OpTypeVector %3 4
|
||||||
|
%4 = OpConstant %3 2
|
||||||
|
%5 = OpConstantComposite %2 %4 %4 %4 %4
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_F32_Vec2) {
|
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_F32_Vec2) {
|
||||||
auto* cast = vec3<f32>(2.0f, vec2<f32>(2.0f, 2.0f));
|
auto* cast = vec3<f32>(2.0f, vec2<f32>(2.0f, 2.0f));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue