tint: Fix emitting identity matrix ctor in HLSL

This patch fix the issue of identity matrix constructors in HLSL. This
patch also fix dawn e2e tests for identity matrix constructors and zero
matrix constructors.

Bug: tint:1596, tint:1545
Change-Id: I6c41eb299c1d5f89cf18720611f450abae26d3f4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94042
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com>
This commit is contained in:
Zhaoming Jiang
2022-06-24 17:21:59 +00:00
committed by Dawn LUCI CQ
parent f47887d207
commit c5f7e8f0bc
164 changed files with 1583 additions and 56 deletions

View File

@@ -1110,52 +1110,13 @@ bool GeneratorImpl::EmitTypeConstructor(std::ostream& out,
return EmitZeroValue(out, type);
}
if (auto* mat = call->Type()->As<sem::Matrix>()) {
if (ctor->Parameters().size() == 1) {
// Matrix constructor with single scalar.
auto fn = utils::GetOrCreate(matrix_scalar_ctors_, mat, [&]() -> std::string {
TextBuffer b;
TINT_DEFER(helpers_.Append(b));
auto name = UniqueIdentifier("build_mat" + std::to_string(mat->columns()) + "x" +
std::to_string(mat->rows()));
{
auto l = line(&b);
if (!EmitType(l, mat, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return "";
}
l << " " << name << "(";
if (!EmitType(l, mat->type(), ast::StorageClass::kNone, ast::Access::kUndefined,
"")) {
return "";
}
l << " value) {";
}
{
ScopedIndent si(&b);
auto l = line(&b);
l << "return ";
if (!EmitType(l, mat, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return "";
}
l << "(";
for (uint32_t i = 0; i < mat->columns() * mat->rows(); i++) {
l << ((i > 0) ? ", value" : "value");
}
l << ");";
}
line(&b) << "}";
return name;
});
if (fn.empty()) {
return false;
}
out << fn << "(";
if (!EmitExpression(out, call->Arguments()[0]->Declaration())) {
return false;
}
out << ")";
return true;
// Single parameter matrix initializers must be identity constructor.
// It could also be conversions between f16 and f32 matrix when f16 is properly supported.
if (type->Is<sem::Matrix>() && call->Arguments().size() == 1) {
if (!ctor->Parameters()[0]->Type()->UnwrapRef()->is_float_matrix()) {
TINT_UNREACHABLE(Writer, diagnostics_)
<< "found a single-parameter matrix constructor that is not identity constructor";
return false;
}
}

View File

@@ -223,6 +223,24 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Empty) {
EXPECT_THAT(gen.result(), HasSubstr("float2x3 tint_symbol = float2x3((0.0f).xxx, (0.0f).xxx)"));
}
TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Identity) {
// fn f() {
// var m_1: mat4x4<f32> = mat4x4<f32>();
// var m_2: mat4x4<f32> = mat4x4<f32>(m_1);
// }
auto* m_1 = Var("m_1", ty.mat4x4(ty.f32()), mat4x4<f32>());
auto* m_2 = Var("m_2", ty.mat4x4(ty.f32()), mat4x4<f32>(m_1));
WrapInFunction(m_1, m_2);
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_THAT(gen.result(), HasSubstr("float4x4 m_2 = float4x4(m_1);"));
}
TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Array) {
WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1_f, 2_f, 3_f),
vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));