dawn-cmake/src/transform/wrap_arrays_in_structs_test.cc
Ben Clayton 0597a2b51b Add transform/WrapArraysInStructs
And replace the MSL writer's logic to do this with the transform.

We need to do the same thing in HLSL, and in the future GLSL too.

Partially reverts fbfde720

Change-Id: Ie280e011bc3ded8e15ccacc0aeb12da3c2407389
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/54242
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
2021-06-16 09:19:36 +00:00

318 lines
5.8 KiB
C++

// Copyright 2021 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/transform/wrap_arrays_in_structs.h"
#include <memory>
#include <utility>
#include "src/transform/test_helper.h"
namespace tint {
namespace transform {
namespace {
using WrapArraysInStructsTest = TransformTest;
TEST_F(WrapArraysInStructsTest, EmptyModule) {
auto* src = "";
auto* expect = "";
auto got = Run<WrapArraysInStructs>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(WrapArraysInStructsTest, ArrayAsGlobal) {
auto* src = R"(
var<private> arr : array<i32, 4>;
)";
auto* expect = R"(
struct tint_array_wrapper {
arr : array<i32, 4>;
};
var<private> arr : tint_array_wrapper;
)";
auto got = Run<WrapArraysInStructs>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(WrapArraysInStructsTest, ArrayAsFunctionVar) {
auto* src = R"(
fn f() {
var arr : array<i32, 4>;
let x = arr[3];
}
)";
auto* expect = R"(
struct tint_array_wrapper {
arr : array<i32, 4>;
};
fn f() {
var arr : tint_array_wrapper;
let x = arr.arr[3];
}
)";
auto got = Run<WrapArraysInStructs>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(WrapArraysInStructsTest, ArrayAsParam) {
auto* src = R"(
fn f(a : array<i32, 4>) -> i32 {
return a[2];
}
)";
auto* expect = R"(
struct tint_array_wrapper {
arr : array<i32, 4>;
};
fn f(a : tint_array_wrapper) -> i32 {
return a.arr[2];
}
)";
auto got = Run<WrapArraysInStructs>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(WrapArraysInStructsTest, ArrayAsReturn) {
auto* src = R"(
fn f() -> array<i32, 4> {
return array<i32, 4>(1, 2, 3, 4);
}
)";
auto* expect = R"(
struct tint_array_wrapper {
arr : array<i32, 4>;
};
fn f() -> tint_array_wrapper {
return tint_array_wrapper(array<i32, 4>(1, 2, 3, 4));
}
)";
auto got = Run<WrapArraysInStructs>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(WrapArraysInStructsTest, ArrayAlias) {
auto* src = R"(
type Inner = array<i32, 2>;
type Array = array<Inner, 2>;
fn f() {
var arr : Array;
arr = Array();
arr = Array(Inner(1, 2), Inner(3, 4));
let vals : Array = Array(Inner(1, 2), Inner(3, 4));
arr = vals;
let x = arr[3];
}
)";
auto* expect = R"(
struct tint_array_wrapper {
arr : array<i32, 2>;
};
type Inner = tint_array_wrapper;
struct tint_array_wrapper_1 {
arr : array<tint_array_wrapper, 2>;
};
type Array = tint_array_wrapper_1;
fn f() {
var arr : tint_array_wrapper_1;
arr = tint_array_wrapper_1(array<tint_array_wrapper, 2>());
arr = tint_array_wrapper_1(array<tint_array_wrapper, 2>(tint_array_wrapper(array<i32, 2>(1, 2)), tint_array_wrapper(array<i32, 2>(3, 4))));
let vals : tint_array_wrapper_1 = tint_array_wrapper_1(array<tint_array_wrapper, 2>(tint_array_wrapper(array<i32, 2>(1, 2)), tint_array_wrapper(array<i32, 2>(3, 4))));
arr = vals;
let x = arr.arr[3];
}
)";
auto got = Run<WrapArraysInStructs>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(WrapArraysInStructsTest, ArraysInStruct) {
auto* src = R"(
struct S {
a : array<i32, 4>;
b : array<i32, 8>;
c : array<i32, 4>;
};
)";
auto* expect = R"(
struct tint_array_wrapper {
arr : array<i32, 4>;
};
struct tint_array_wrapper_1 {
arr : array<i32, 8>;
};
struct S {
a : tint_array_wrapper;
b : tint_array_wrapper_1;
c : tint_array_wrapper;
};
)";
auto got = Run<WrapArraysInStructs>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(WrapArraysInStructsTest, ArraysOfArraysInStruct) {
auto* src = R"(
struct S {
a : array<i32, 4>;
b : array<array<i32, 4>, 4>;
c : array<array<array<i32, 4>, 4>, 4>;
};
)";
auto* expect = R"(
struct tint_array_wrapper {
arr : array<i32, 4>;
};
struct tint_array_wrapper_1 {
arr : array<tint_array_wrapper, 4>;
};
struct tint_array_wrapper_2 {
arr : array<tint_array_wrapper_1, 4>;
};
struct S {
a : tint_array_wrapper;
b : tint_array_wrapper_1;
c : tint_array_wrapper_2;
};
)";
auto got = Run<WrapArraysInStructs>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(WrapArraysInStructsTest, AccessArraysOfArraysInStruct) {
auto* src = R"(
struct S {
a : array<i32, 4>;
b : array<array<i32, 4>, 4>;
c : array<array<array<i32, 4>, 4>, 4>;
};
fn f(s : S) -> i32 {
return s.a[2] + s.b[1][2] + s.c[3][1][2];
}
)";
auto* expect = R"(
struct tint_array_wrapper {
arr : array<i32, 4>;
};
struct tint_array_wrapper_1 {
arr : array<tint_array_wrapper, 4>;
};
struct tint_array_wrapper_2 {
arr : array<tint_array_wrapper_1, 4>;
};
struct S {
a : tint_array_wrapper;
b : tint_array_wrapper_1;
c : tint_array_wrapper_2;
};
fn f(s : S) -> i32 {
return ((s.a.arr[2] + s.b.arr[1].arr[2]) + s.c.arr[3].arr[1].arr[2]);
}
)";
auto got = Run<WrapArraysInStructs>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(WrapArraysInStructsTest, DeclarationOrder) {
auto* src = R"(
type T0 = i32;
type T1 = array<i32, 1>;
type T2 = i32;
fn f1(a : array<i32, 2>) {
}
type T3 = i32;
fn f2() {
var v : array<i32, 3>;
}
)";
auto* expect = R"(
type T0 = i32;
struct tint_array_wrapper {
arr : array<i32, 1>;
};
type T1 = tint_array_wrapper;
type T2 = i32;
struct tint_array_wrapper_1 {
arr : array<i32, 2>;
};
fn f1(a : tint_array_wrapper_1) {
}
type T3 = i32;
struct tint_array_wrapper_2 {
arr : array<i32, 3>;
};
fn f2() {
var v : tint_array_wrapper_2;
}
)";
auto got = Run<WrapArraysInStructs>(src);
EXPECT_EQ(expect, str(got));
}
} // namespace
} // namespace transform
} // namespace tint