tint: Preserve padding in matrices with three rows

The PreservePadding transform now decomposes writes to matrices with
three rows into separate column vector writes, to avoid modifying
padding between columns.

Bug: tint:1571
Change-Id: If575f79bb87f52810783fd3338e2f3ce3228ab2e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121600
Auto-Submit: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: James Price <jrprice@google.com>
This commit is contained in:
James Price
2023-02-27 16:06:54 +00:00
committed by Dawn LUCI CQ
parent fe19fee3ea
commit 6176c85be8
84 changed files with 3733 additions and 1968 deletions

View File

@@ -147,6 +147,18 @@ struct PreservePadding::State {
return body;
});
},
[&](const type::Matrix* mat) {
// Call a helper function that assigns each column separately.
return call_helper([&]() {
utils::Vector<const ast::Statement*, 4> body;
for (uint32_t i = 0; i < mat->columns(); i++) {
body.Push(MakeAssignment(mat->ColumnType(),
b.IndexAccessor(b.Deref(kDestParamName), u32(i)),
b.IndexAccessor(kValueParamName, u32(i))));
}
return body;
});
},
[&](const sem::Struct* str) {
// Call a helper function that assigns each member separately.
return call_helper([&]() {
@@ -179,6 +191,13 @@ struct PreservePadding::State {
}
return HasPadding(elem_ty);
},
[&](const type::Matrix* mat) {
auto* col_ty = mat->ColumnType();
if (mat->ColumnStride() > col_ty->Size()) {
return true;
}
return HasPadding(col_ty);
},
[&](const sem::Struct* str) {
uint32_t current_offset = 0;
for (auto* member : str->Members()) {

View File

@@ -466,6 +466,125 @@ fn foo() {
EXPECT_EQ(expect, str(got));
}
TEST_F(PreservePaddingTest, Mat3x3) {
auto* src = R"(
@group(0) @binding(0) var<storage, read_write> m : mat3x3<f32>;
@compute @workgroup_size(1)
fn foo() {
m = mat3x3<f32>();
}
)";
auto* expect = R"(
enable chromium_experimental_full_ptr_parameters;
@group(0) @binding(0) var<storage, read_write> m : mat3x3<f32>;
fn assign_and_preserve_padding(dest : ptr<storage, mat3x3<f32>, read_write>, value : mat3x3<f32>) {
(*(dest))[0u] = value[0u];
(*(dest))[1u] = value[1u];
(*(dest))[2u] = value[2u];
}
@compute @workgroup_size(1)
fn foo() {
assign_and_preserve_padding(&(m), mat3x3<f32>());
}
)";
auto got = Run<PreservePadding>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(PreservePaddingTest, Mat3x3_InStruct) {
auto* src = R"(
struct S {
a : u32,
m : mat3x3<f32>,
}
@group(0) @binding(0) var<storage, read_write> buffer : S;
@compute @workgroup_size(1)
fn foo() {
buffer = S();
}
)";
auto* expect = R"(
enable chromium_experimental_full_ptr_parameters;
struct S {
a : u32,
m : mat3x3<f32>,
}
@group(0) @binding(0) var<storage, read_write> buffer : S;
fn assign_and_preserve_padding_1(dest : ptr<storage, mat3x3<f32>, read_write>, value : mat3x3<f32>) {
(*(dest))[0u] = value[0u];
(*(dest))[1u] = value[1u];
(*(dest))[2u] = value[2u];
}
fn assign_and_preserve_padding(dest : ptr<storage, S, read_write>, value : S) {
(*(dest)).a = value.a;
assign_and_preserve_padding_1(&((*(dest)).m), value.m);
}
@compute @workgroup_size(1)
fn foo() {
assign_and_preserve_padding(&(buffer), S());
}
)";
auto got = Run<PreservePadding>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(PreservePaddingTest, ArrayOfMat3x3) {
auto* src = R"(
@group(0) @binding(0) var<storage, read_write> arr_m : array<mat3x3<f32>, 4>;
@compute @workgroup_size(1)
fn foo() {
arr_m = array<mat3x3<f32>, 4>();
arr_m[0] = mat3x3<f32>();
}
)";
auto* expect = R"(
enable chromium_experimental_full_ptr_parameters;
@group(0) @binding(0) var<storage, read_write> arr_m : array<mat3x3<f32>, 4>;
fn assign_and_preserve_padding_1(dest : ptr<storage, mat3x3<f32>, read_write>, value : mat3x3<f32>) {
(*(dest))[0u] = value[0u];
(*(dest))[1u] = value[1u];
(*(dest))[2u] = value[2u];
}
fn assign_and_preserve_padding(dest : ptr<storage, array<mat3x3<f32>, 4u>, read_write>, value : array<mat3x3<f32>, 4u>) {
for(var i = 0u; (i < 4u); i = (i + 1u)) {
assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
}
}
@compute @workgroup_size(1)
fn foo() {
assign_and_preserve_padding(&(arr_m), array<mat3x3<f32>, 4>());
assign_and_preserve_padding_1(&(arr_m[0]), mat3x3<f32>());
}
)";
auto got = Run<PreservePadding>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(PreservePaddingTest, NoModify_Vec3) {
auto* src = R"(
@group(0) @binding(0) var<storage, read_write> v : vec3<u32>;
@@ -524,23 +643,6 @@ fn foo() {
EXPECT_EQ(expect, str(got));
}
TEST_F(PreservePaddingTest, NoModify_Mat3x3) {
auto* src = R"(
@group(0) @binding(0) var<storage, read_write> v : mat3x3<f32>;
@compute @workgroup_size(1)
fn foo() {
v = mat3x3<f32>();
}
)";
auto* expect = src;
auto got = Run<PreservePadding>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(PreservePaddingTest, NoModify_StructNoPadding) {
auto* src = R"(
struct S {

View File

@@ -241,13 +241,22 @@ INSTANTIATE_TEST_SUITE_P(GlslGeneratorImplTest_MemberAccessor,
TypeCase{ty_vec4<f32>, "data.inner.b = value"},
TypeCase{ty_vec4<i32>, "data.inner.b = value"},
TypeCase{ty_mat2x2<f32>, "data.inner.b = value"},
TypeCase{ty_mat2x3<f32>, "data.inner.b = value"},
TypeCase{ty_mat2x3<f32>, R"(
data.inner.b[0] = value[0u];
data.inner.b[1] = value[1u];)"},
TypeCase{ty_mat2x4<f32>, "data.inner.b = value"},
TypeCase{ty_mat3x2<f32>, "data.inner.b = value"},
TypeCase{ty_mat3x3<f32>, "data.inner.b = value"},
TypeCase{ty_mat3x3<f32>, R"(
data.inner.b[0] = value[0u];
data.inner.b[1] = value[1u];
data.inner.b[2] = value[2u];)"},
TypeCase{ty_mat3x4<f32>, "data.inner.b = value"},
TypeCase{ty_mat4x2<f32>, "data.inner.b = value"},
TypeCase{ty_mat4x3<f32>, "data.inner.b = value"},
TypeCase{ty_mat4x3<f32>, R"(
data.inner.b[0] = value[0u];
data.inner.b[1] = value[1u];
data.inner.b[2] = value[2u];
data.inner.b[3] = value[3u];)"},
TypeCase{ty_mat4x4<f32>, "data.inner.b = value"}));
TEST_F(GlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_Matrix_Empty) {
@@ -286,8 +295,13 @@ layout(binding = 0, std430) buffer data_block_ssbo {
Data inner;
} data;
void assign_and_preserve_padding_data_b(mat2x3 value) {
data.inner.b[0] = value[0u];
data.inner.b[1] = value[1u];
}
void tint_symbol() {
data.inner.b = mat2x3(vec3(0.0f), vec3(0.0f));
assign_and_preserve_padding_data_b(mat2x3(vec3(0.0f), vec3(0.0f)));
}
void main() {