spirv-reader: support OpTranspose Change-Id: If338b22b703257e863e511579cfd3abcaa0bdfe7 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48761 Auto-Submit: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Alan Baker <alanbaker@google.com> Reviewed-by: Alan Baker <alanbaker@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc index 888f7cc..a6270c1 100644 --- a/src/reader/spirv/function.cc +++ b/src/reader/spirv/function.cc
@@ -175,6 +175,8 @@ return "isNan"; case SpvOpIsInf: return "isInf"; + case SpvOpTranspose: + return "transpose"; default: break; }
diff --git a/src/reader/spirv/function_arithmetic_test.cc b/src/reader/spirv/function_arithmetic_test.cc index 9a05b46..869729a 100644 --- a/src/reader/spirv/function_arithmetic_test.cc +++ b/src/reader/spirv/function_arithmetic_test.cc
@@ -57,11 +57,15 @@ %v2float_50_60 = OpConstantComposite %v2float %float_50 %float_60 %v2float_60_50 = OpConstantComposite %v2float %float_60 %float_50 %v3float_50_60_70 = OpConstantComposite %v2float %float_50 %float_60 %float_70 + %v3float_60_70_50 = OpConstantComposite %v2float %float_60 %float_70 %float_50 %m2v2float = OpTypeMatrix %v2float 2 + %m2v3float = OpTypeMatrix %v3float 2 + %m3v2float = OpTypeMatrix %v2float 3 %m2v2float_a = OpConstantComposite %m2v2float %v2float_50_60 %v2float_60_50 %m2v2float_b = OpConstantComposite %m2v2float %v2float_60_50 %v2float_50_60 - %m2v3float = OpTypeMatrix %v3float 2 + %m3v2float_a = OpConstantComposite %m3v2float %v2float_50_60 %v2float_60_50 %v2float_50_60 + %m2v3float_a = OpConstantComposite %m2v3float %v3float_50_60_70 %v3float_60_70_50 )"; } @@ -1551,6 +1555,108 @@ ArgAndTypeData{"v2float", "v2float_50_60", "__vec_2__f32"}, ArgAndTypeData{"v3float", "v3float_50_60_70", "__vec_3__f32"}))); +TEST_F(SpvUnaryArithTest, Transpose_2x2) { + const auto assembly = CommonTypes() + R"( + %100 = OpFunction %void None %voidfn + %entry = OpLabel + %1 = OpCopyObject %m2v2float %m2v2float_a + %2 = OpTranspose %m2v2float %1 + OpReturn + OpFunctionEnd + )"; + auto p = parser(test::Assemble(assembly)); + ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); + FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100)); + EXPECT_TRUE(fe.EmitBody()) << p->error(); + const auto* expected = R"( +VariableDeclStatement{ + VariableConst{ + x_2 + none + __mat_2_2__f32 + { + Call[not set]{ + Identifier[not set]{transpose} + ( + Identifier[not set]{x_1} + ) + } + } + } +})"; + const auto got = ToString(p->builder(), fe.ast_body()); + EXPECT_THAT(got, HasSubstr(expected)) << got; +} + +TEST_F(SpvUnaryArithTest, Transpose_2x3) { + const auto assembly = CommonTypes() + R"( + %100 = OpFunction %void None %voidfn + %entry = OpLabel + %1 = OpCopyObject %m2v3float %m2v3float_a + %2 = OpTranspose %m3v2float %1 + OpReturn + OpFunctionEnd + )"; + auto p = parser(test::Assemble(assembly)); + ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); + FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100)); + EXPECT_TRUE(fe.EmitBody()) << p->error(); + // Note, in the AST dump mat_2_3 means 2 rows and 3 columns. + // So the column vectors have 2 elements. + // That is, %m3v2float is __mat_2_3__f32. + const auto* expected = R"( +VariableDeclStatement{ + VariableConst{ + x_2 + none + __mat_2_3__f32 + { + Call[not set]{ + Identifier[not set]{transpose} + ( + Identifier[not set]{x_1} + ) + } + } + } +})"; + const auto got = ToString(p->builder(), fe.ast_body()); + EXPECT_THAT(got, HasSubstr(expected)) << got; +} + +TEST_F(SpvUnaryArithTest, Transpose_3x2) { + const auto assembly = CommonTypes() + R"( + %100 = OpFunction %void None %voidfn + %entry = OpLabel + %1 = OpCopyObject %m3v2float %m3v2float_a + %2 = OpTranspose %m2v3float %1 + OpReturn + OpFunctionEnd + )"; + auto p = parser(test::Assemble(assembly)); + ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); + FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100)); + EXPECT_TRUE(fe.EmitBody()) << p->error(); + const auto* expected = R"( +VariableDeclStatement{ + VariableConst{ + x_2 + none + __mat_3_2__f32 + { + Call[not set]{ + Identifier[not set]{transpose} + ( + Identifier[not set]{x_1} + ) + } + } + } +})"; + const auto got = ToString(p->builder(), fe.ast_body()); + EXPECT_THAT(got, HasSubstr(expected)) << got; +} + // TODO(dneto): OpSRem. Missing from WGSL // https://github.com/gpuweb/gpuweb/issues/702