Capture: Capture Storage Texture
Bug: 451460562
Change-Id: I6a6a69646247fb1f6b41299b1280cb1545359fa3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/270174
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Gregg Tavares <gman@chromium.org>
diff --git a/src/dawn/native/webgpu/BindGroupLayoutWGPU.cpp b/src/dawn/native/webgpu/BindGroupLayoutWGPU.cpp
index 2d45dd0..6b60248 100644
--- a/src/dawn/native/webgpu/BindGroupLayoutWGPU.cpp
+++ b/src/dawn/native/webgpu/BindGroupLayoutWGPU.cpp
@@ -129,6 +129,18 @@
Serialize(captureContext, entry);
return {};
},
+ [&](const StorageTextureBindingInfo& info) -> MaybeError {
+ schema::BindGroupLayoutEntryTypeStorageTextureBinding entry{{
+ .binding = binding,
+ .data{{
+ .format = info.format,
+ .viewDimension = info.viewDimension,
+ .access = info.access,
+ }},
+ }};
+ Serialize(captureContext, entry);
+ return {};
+ },
[&](const auto& info) -> MaybeError {
return DAWN_INTERNAL_ERROR("Unsupported bind layout entry type");
}));
diff --git a/src/dawn/native/webgpu/BindGroupWGPU.cpp b/src/dawn/native/webgpu/BindGroupWGPU.cpp
index 9586948..68c7af3 100644
--- a/src/dawn/native/webgpu/BindGroupWGPU.cpp
+++ b/src/dawn/native/webgpu/BindGroupWGPU.cpp
@@ -140,6 +140,9 @@
DAWN_TRY(MatchVariant(
bindingInfo.bindingLayout,
+ [&](const StorageTextureBindingInfo& info) -> MaybeError {
+ return captureContext.AddResource(GetBindingAsTextureView(bindingIndex));
+ },
[&](const TextureBindingInfo& info) -> MaybeError {
return captureContext.AddResource(GetBindingAsTextureView(bindingIndex));
},
@@ -184,6 +187,16 @@
}};
Serialize(captureContext, data);
},
+ [&](const StorageTextureBindingInfo& info) {
+ const auto& entry = GetBindingAsTextureView(bindingIndex);
+ schema::BindGroupEntryTypeTextureBinding data{{
+ .binding = binding,
+ .data{{
+ .textureViewId = captureContext.GetId(entry),
+ }},
+ }};
+ Serialize(captureContext, data);
+ },
[&](const TextureBindingInfo& info) {
const auto& entry = GetBindingAsTextureView(bindingIndex);
schema::BindGroupEntryTypeTextureBinding data{{
diff --git a/src/dawn/replay/Replay.cpp b/src/dawn/replay/Replay.cpp
index ee98bc3..eea4b7d 100644
--- a/src/dawn/replay/Replay.cpp
+++ b/src/dawn/replay/Replay.cpp
@@ -265,6 +265,23 @@
});
break;
}
+ case schema::BindGroupLayoutEntryType::StorageTextureBinding: {
+ schema::BindGroupLayoutEntryTypeStorageTextureBindingData data;
+ DAWN_TRY(Deserialize(readHead, &data));
+
+ entries.push_back({
+ .binding = binding.binding,
+ .visibility = binding.visibility,
+ .bindingArraySize = binding.bindingArraySize,
+ .storageTexture =
+ {
+ .access = data.access,
+ .format = data.format,
+ .viewDimension = data.viewDimension,
+ },
+ });
+ break;
+ }
default:
return DAWN_INTERNAL_ERROR("unhandled bind group layout entry type");
}
diff --git a/src/dawn/serialization/Schema.h b/src/dawn/serialization/Schema.h
index d0ccaab..df96c75 100644
--- a/src/dawn/serialization/Schema.h
+++ b/src/dawn/serialization/Schema.h
@@ -259,6 +259,14 @@
DAWN_REPLAY_MAKE_BINDGROUP_LAYOUT_VARIANT(BufferBinding, BUFFER_BIND_GROUP_LAYOUT_MEMBER){};
+#define STORAGE_TEXTURE_BIND_GROUP_LAYOUT_MEMBER(X) \
+ X(wgpu::TextureFormat, format) \
+ X(wgpu::TextureViewDimension, viewDimension) \
+ X(wgpu::StorageTextureAccess, access)
+
+DAWN_REPLAY_MAKE_BINDGROUP_LAYOUT_VARIANT(StorageTextureBinding,
+ STORAGE_TEXTURE_BIND_GROUP_LAYOUT_MEMBER){};
+
#define BIND_GROUP_LAYOUT_MEMBER(X) X(uint32_t, numEntries)
DAWN_REPLAY_SERIALIZABLE(struct, BindGroupLayout, BIND_GROUP_LAYOUT_MEMBER){};
diff --git a/src/dawn/tests/white_box/CaptureAndReplayTests.cpp b/src/dawn/tests/white_box/CaptureAndReplayTests.cpp
index 8d24aa3..0dec83f 100644
--- a/src/dawn/tests/white_box/CaptureAndReplayTests.cpp
+++ b/src/dawn/tests/white_box/CaptureAndReplayTests.cpp
@@ -1457,6 +1457,80 @@
}
}
+// Capture and replay a pass that uses a storage texture
+TEST_P(CaptureAndReplayTests, CaptureStorageTextureUsageWithExplicitBindGroupLayout) {
+ wgpu::BindGroupLayoutEntry entries[1];
+ entries[0].binding = 0;
+ entries[0].visibility = wgpu::ShaderStage::Compute;
+ entries[0].storageTexture.access = wgpu::StorageTextureAccess::WriteOnly;
+ entries[0].storageTexture.format = wgpu::TextureFormat::RGBA8Uint;
+
+ wgpu::BindGroupLayoutDescriptor bglDesc;
+ bglDesc.entryCount = 1;
+ bglDesc.entries = entries;
+ wgpu::BindGroupLayout layout = device.CreateBindGroupLayout(&bglDesc);
+
+ wgpu::PipelineLayoutDescriptor plDesc;
+ plDesc.bindGroupLayoutCount = 1;
+ plDesc.bindGroupLayouts = &layout;
+ wgpu::PipelineLayout pipelineLayout = device.CreatePipelineLayout(&plDesc);
+
+ wgpu::TextureDescriptor textureDesc;
+ textureDesc.label = "myTexture";
+ textureDesc.size = {1, 1, 1};
+ textureDesc.format = wgpu::TextureFormat::RGBA8Uint;
+ textureDesc.usage = wgpu::TextureUsage::StorageBinding | wgpu::TextureUsage::CopySrc;
+ wgpu::Texture texture = device.CreateTexture(&textureDesc);
+
+ const char* shader = R"(
+ @group(0) @binding(0) var tex: texture_storage_2d<rgba8uint, write>;
+
+ @compute @workgroup_size(1) fn main() {
+ textureStore(tex, vec2u(0), vec4u(0x11, 0x22, 0x33, 0x44));
+ }
+ )";
+ auto module = utils::CreateShaderModule(device, shader);
+
+ wgpu::ComputePipelineDescriptor csDesc;
+ csDesc.layout = pipelineLayout;
+ csDesc.compute.module = module;
+ wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);
+
+ wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
+ {
+ {0, texture.CreateView()},
+ });
+
+ wgpu::CommandBuffer commands;
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
+ pass.SetBindGroup(0, bindGroup);
+ pass.SetPipeline(pipeline);
+ pass.DispatchWorkgroups(1);
+ pass.End();
+
+ commands = encoder.Finish();
+ }
+
+ // --- capture ---
+ auto recorder = Recorder::CreateAndStart(device);
+
+ queue.Submit(1, &commands);
+
+ // --- replay ---
+ auto capture = recorder.Finish();
+ auto replay = capture.Replay(device);
+
+ {
+ wgpu::Texture texture = replay->GetObjectByLabel<wgpu::Texture>("myTexture");
+ ASSERT_NE(texture, nullptr);
+
+ uint8_t expected[] = {0x11, 0x22, 0x33, 0x44};
+ EXPECT_TEXTURE_EQ(&expected[0], texture, {0, 0}, {1, 1}, 0, wgpu::TextureAspect::All);
+ }
+}
+
DAWN_INSTANTIATE_TEST(CaptureAndReplayTests, WebGPUBackend());
} // anonymous namespace