Add transform/PadArrayElements

Replaces arrays with an explicit stride with an array to a structure holding the element padded with a `[[size]]` decoration.

Note that the HLSL writer is still not correctly emitting structure fields with a `[[size]]`, which will be fixed in a follow up change.

Bug: tint:182
Bug: tint:895
Fixed: tint:180
Fixed: tint:649
Change-Id: Ic135dfc89309ac805507e9f39392577c7f82d154
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/54582
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
Ben Clayton
2021-06-16 09:50:11 +00:00
committed by Ben Clayton
parent 92b1991271
commit 31936f375f
19 changed files with 711 additions and 86 deletions

View File

@@ -28,13 +28,13 @@ Array::Array(const Type* element,
uint32_t align,
uint32_t size,
uint32_t stride,
bool stride_implicit)
uint32_t implicit_stride)
: element_(element),
count_(count),
align_(align),
size_(size),
stride_(stride),
stride_implicit_(stride_implicit) {
implicit_stride_(implicit_stride) {
TINT_ASSERT(element_);
}
@@ -44,14 +44,14 @@ std::string Array::type_name() const {
type_name += "_align_" + std::to_string(align_);
type_name += "_size_" + std::to_string(size_);
type_name += "_stride_" + std::to_string(stride_);
// Note: stride_implicit is not part of the type_name string as this is a
// property derived from the other fields.
// Note: implicit_stride is not part of the type_name string as this is
// derived from the element type
return type_name;
}
std::string Array::FriendlyName(const SymbolTable& symbols) const {
std::ostringstream out;
if (!stride_implicit_) {
if (!IsStrideImplicit()) {
out << "[[stride(" << stride_ << ")]] ";
}
out << "array<" << element_->FriendlyName(symbols);

View File

@@ -42,14 +42,15 @@ class Array : public Castable<Array, Type> {
/// @param size the byte size of the array
/// @param stride the number of bytes from the start of one element of the
/// array to the start of the next element
/// @param stride_implicit is true if the value of `stride` matches the
/// element's natural stride.
/// @param implicit_stride the number of bytes from the start of one element
/// of the array to the start of the next element, if there was no [[stride]]
/// decoration applied.
Array(Type const* element,
uint32_t count,
uint32_t align,
uint32_t size,
uint32_t stride,
bool stride_implicit);
uint32_t implicit_stride);
/// @return the array element type
Type const* ElemType() const { return element_; }
@@ -72,9 +73,14 @@ class Array : public Castable<Array, Type> {
/// array to the start of the next element
uint32_t Stride() const { return stride_; }
/// @returns true if the value returned by Stride() does matches the
/// element's natural stride
bool IsStrideImplicit() const { return stride_implicit_; }
/// @returns the number of bytes from the start of one element of the
/// array to the start of the next element, if there was no [[stride]]
/// decoration applied
uint32_t ImplicitStride() const { return implicit_stride_; }
/// @returns true if the value returned by Stride() matches the element's
/// natural stride
bool IsStrideImplicit() const { return stride_ == implicit_stride_; }
/// @returns true if this array is runtime sized
bool IsRuntimeSized() const { return count_ == 0; }
@@ -93,7 +99,7 @@ class Array : public Castable<Array, Type> {
uint32_t const align_;
uint32_t const size_;
uint32_t const stride_;
bool const stride_implicit_;
uint32_t const implicit_stride_;
};
} // namespace sem

View File

@@ -23,57 +23,59 @@ using ArrayTest = TestHelper;
TEST_F(ArrayTest, CreateSizedArray) {
U32 u32;
auto* arr = create<Array>(&u32, 2, 4, 8, 16, true);
auto* arr = create<Array>(&u32, 2, 4, 8, 32, 16);
EXPECT_EQ(arr->ElemType(), &u32);
EXPECT_EQ(arr->Count(), 2u);
EXPECT_EQ(arr->Align(), 4u);
EXPECT_EQ(arr->SizeInBytes(), 8u);
EXPECT_EQ(arr->Stride(), 16u);
EXPECT_TRUE(arr->IsStrideImplicit());
EXPECT_EQ(arr->Stride(), 32u);
EXPECT_EQ(arr->ImplicitStride(), 16u);
EXPECT_FALSE(arr->IsStrideImplicit());
EXPECT_FALSE(arr->IsRuntimeSized());
}
TEST_F(ArrayTest, CreateRuntimeArray) {
U32 u32;
auto* arr = create<Array>(&u32, 0, 4, 8, 16, true);
auto* arr = create<Array>(&u32, 0, 4, 8, 32, 32);
EXPECT_EQ(arr->ElemType(), &u32);
EXPECT_EQ(arr->Count(), 0u);
EXPECT_EQ(arr->Align(), 4u);
EXPECT_EQ(arr->SizeInBytes(), 8u);
EXPECT_EQ(arr->Stride(), 16u);
EXPECT_EQ(arr->Stride(), 32u);
EXPECT_EQ(arr->ImplicitStride(), 32u);
EXPECT_TRUE(arr->IsStrideImplicit());
EXPECT_TRUE(arr->IsRuntimeSized());
}
TEST_F(ArrayTest, TypeName) {
I32 i32;
auto* arr = create<Array>(&i32, 2, 0, 4, 4, true);
auto* arr = create<Array>(&i32, 2, 0, 4, 4, 4);
EXPECT_EQ(arr->type_name(), "__array__i32_count_2_align_0_size_4_stride_4");
}
TEST_F(ArrayTest, FriendlyNameRuntimeSized) {
auto* arr = create<Array>(create<I32>(), 0, 0, 4, 4, true);
auto* arr = create<Array>(create<I32>(), 0, 0, 4, 4, 4);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
}
TEST_F(ArrayTest, FriendlyNameStaticSized) {
auto* arr = create<Array>(create<I32>(), 5, 4, 20, 4, true);
auto* arr = create<Array>(create<I32>(), 5, 4, 20, 4, 4);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
}
TEST_F(ArrayTest, FriendlyNameRuntimeSizedNonImplicitStride) {
auto* arr = create<Array>(create<I32>(), 0, 0, 4, 4, false);
EXPECT_EQ(arr->FriendlyName(Symbols()), "[[stride(4)]] array<i32>");
auto* arr = create<Array>(create<I32>(), 0, 0, 4, 8, 4);
EXPECT_EQ(arr->FriendlyName(Symbols()), "[[stride(8)]] array<i32>");
}
TEST_F(ArrayTest, FriendlyNameStaticSizedNonImplicitStride) {
auto* arr = create<Array>(create<I32>(), 5, 4, 20, 4, false);
EXPECT_EQ(arr->FriendlyName(Symbols()), "[[stride(4)]] array<i32, 5>");
auto* arr = create<Array>(create<I32>(), 5, 4, 20, 8, 4);
EXPECT_EQ(arr->FriendlyName(Symbols()), "[[stride(8)]] array<i32, 5>");
}
TEST_F(ArrayTest, TypeName_RuntimeArray) {
I32 i32;
auto* arr = create<Array>(&i32, 2, 4, 8, 16, true);
auto* arr = create<Array>(&i32, 2, 4, 8, 16, 16);
EXPECT_EQ(arr->type_name(), "__array__i32_count_2_align_4_size_8_stride_16");
}