[hlsl] Add vector element storage store support
This CL adds support for storing to vector elements in the
DecomposeStorageAccess transform.
Bug: 42251045
Change-Id: Id81a5b4fb672adbc6ae123c32f69dcdb85cc17e2
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/197777
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/hlsl/writer/access_test.cc b/src/tint/lang/hlsl/writer/access_test.cc
index edbb41a..784d0f8 100644
--- a/src/tint/lang/hlsl/writer/access_test.cc
+++ b/src/tint/lang/hlsl/writer/access_test.cc
@@ -1332,14 +1332,15 @@
)");
}
-TEST_F(HlslWriterTest, DISABLED_AccessStoreVectorElement) {
+TEST_F(HlslWriterTest, AccessStoreVectorElement) {
auto* var = b.Var<storage, vec3<f32>, core::Access::kReadWrite>("v");
var->SetBindingPoint(0, 0);
b.ir.root_block->Append(var);
auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
b.Append(func->Block(), [&] {
- b.Store(b.Access(ty.ptr<storage, f32, core::Access::kReadWrite>(), var, 1_u), 2_f);
+ b.StoreVectorElement(b.Access(ty.ptr<storage, vec3<f32>, core::Access::kReadWrite>(), var),
+ 1_u, 2_f);
b.Return(func);
});
@@ -1347,8 +1348,9 @@
EXPECT_EQ(output_.hlsl, R"(
RWByteAddressBuffer v : register(u0);
void foo() {
- v.Store(4u, 2.0f);
+ v.Store(4u, asuint(2.0f));
}
+
)");
}
diff --git a/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc b/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc
index c2e8261..e23e834 100644
--- a/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc
+++ b/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc
@@ -116,7 +116,7 @@
[&](core::ir::StoreVectorElement* s) { StoreVectorElement(s, var, var_ty); },
[&](core::ir::Store* s) {
OffsetData offset{};
- Store(s, var, offset);
+ Store(s, var, s->From(), offset);
},
[&](core::ir::Load* l) {
OffsetData offset{};
@@ -211,8 +211,8 @@
return MakeScalarOrVectorStore(var, from, offset);
}
- // TODO(dsinclair): This currently only handles scalars and entire vectors. Add vector
- // elements, matrices, structs ...
+ // TODO(dsinclair): This currently only handles scalars vectors. Add arrays, matrices,
+ // structs ...
TINT_UNREACHABLE();
}
@@ -513,12 +513,15 @@
Load(ld, var, *offset);
},
- [&](core::ir::StoreVectorElement*) {
- // TODO(dsinclair): Handle store vector elements
+ [&](core::ir::StoreVectorElement* sve) {
+ a->Result(0)->RemoveUsage(usage);
+
+ b.InsertBefore(sve, [&] {
+ UpdateOffsetData(sve->Index(), obj->DeepestElement()->Size(), offset);
+ });
+ Store(sve, var, sve->Value(), *offset);
},
- [&](core::ir::Store* store) { //
- Store(store, var, *offset);
- },
+ [&](core::ir::Store* store) { Store(store, var, store->From(), *offset); },
[&](core::ir::CoreBuiltinCall* call) {
// Array length calls require the access
TINT_ASSERT(call->Func() == core::BuiltinFn::kArrayLength);
@@ -535,12 +538,15 @@
a->Destroy();
}
- void Store(core::ir::Store* store, core::ir::Var* var, OffsetData& offset) {
- b.InsertBefore(store, [&] {
+ void Store(core::ir::Instruction* inst,
+ core::ir::Var* var,
+ core::ir::Value* from,
+ OffsetData& offset) {
+ b.InsertBefore(inst, [&] {
auto* off = OffsetToValue(offset);
- MakeStore(var, store->From(), off);
+ MakeStore(var, from, off);
});
- store->Destroy();
+ inst->Destroy();
}
void Load(core::ir::Instruction* inst, core::ir::Var* var, OffsetData& offset) {
diff --git a/src/tint/lang/hlsl/writer/raise/decompose_storage_access_test.cc b/src/tint/lang/hlsl/writer/raise/decompose_storage_access_test.cc
index ee7653c..134afca 100644
--- a/src/tint/lang/hlsl/writer/raise/decompose_storage_access_test.cc
+++ b/src/tint/lang/hlsl/writer/raise/decompose_storage_access_test.cc
@@ -2506,26 +2506,27 @@
EXPECT_EQ(expect, str());
}
-TEST_F(HlslWriterDecomposeStorageAccessTest, DISABLED_StoreVectorElement) {
+TEST_F(HlslWriterDecomposeStorageAccessTest, StoreVectorElement) {
auto* var = b.Var<storage, vec3<f32>, core::Access::kReadWrite>("v");
var->SetBindingPoint(0, 0);
b.ir.root_block->Append(var);
auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
b.Append(func->Block(), [&] {
- b.Store(b.Access(ty.ptr<storage, f32, core::Access::kReadWrite>(), var, 1_u), 2_f);
+ b.StoreVectorElement(b.Access(ty.ptr<storage, vec3<f32>, core::Access::kReadWrite>(), var),
+ 1_u, 2_f);
b.Return(func);
});
auto* src = R"(
$B1: { # root
- %v:ptr<storage, mat4x4<f32>, read_write> = var @binding_point(0, 0)
+ %v:ptr<storage, vec3<f32>, read_write> = var @binding_point(0, 0)
}
%foo = @fragment func():void {
$B2: {
- %3:ptr<storage, vec4<f32>, read_write> = access %v, 1u
- store_vector_element %3, 2u, 5.0f
+ %3:ptr<storage, vec3<f32>, read_write> = access %v
+ store_vector_element %3, 1u, 2.0f
ret
}
}
@@ -2533,6 +2534,17 @@
ASSERT_EQ(src, str());
auto* expect = R"(
+$B1: { # root
+ %v:hlsl.byte_address_buffer<read_write> = var @binding_point(0, 0)
+}
+
+%foo = @fragment func():void {
+ $B2: {
+ %3:u32 = bitcast 2.0f
+ %4:void = %v.Store 4u, %3
+ ret
+ }
+}
)";
Run(DecomposeStorageAccess);
EXPECT_EQ(expect, str());