Fix leak of Metal counter sample buffers
The blit descriptor allocation was leaking, which references the
counter sample buffer. Fix it by storing the descriptor in a
scoped NSRef
Fixed: dawn:1603
Change-Id: If40e8608db167717a4e07f3cb64a5e98402e3f1a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112861
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/dawn/native/metal/CommandBufferMTL.mm b/src/dawn/native/metal/CommandBufferMTL.mm
index 91aacbf..f1f5131 100644
--- a/src/dawn/native/metal/CommandBufferMTL.mm
+++ b/src/dawn/native/metal/CommandBufferMTL.mm
@@ -334,7 +334,8 @@
API_AVAILABLE(macos(11.0), ios(14.0)) {
commandContext->EndBlit();
- MTLBlitPassDescriptor* descriptor = [[MTLBlitPassDescriptor alloc] init];
+ auto scopedDescriptor = AcquireNSRef([[MTLBlitPassDescriptor alloc] init]);
+ MTLBlitPassDescriptor* descriptor = scopedDescriptor.Get();
if (cmd->querySet.Get() != nullptr) {
descriptor.sampleBufferAttachments[0].sampleBuffer =
ToBackend(cmd->querySet.Get())->GetCounterSampleBuffer();
diff --git a/src/dawn/tests/end2end/QueryTests.cpp b/src/dawn/tests/end2end/QueryTests.cpp
index f8cf53c..9d4ec5a 100644
--- a/src/dawn/tests/end2end/QueryTests.cpp
+++ b/src/dawn/tests/end2end/QueryTests.cpp
@@ -1078,6 +1078,26 @@
EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
}
+// Test calling WriteTimestamp many times into separate query sets.
+// Regression test for crbug.com/dawn/1603.
+TEST_P(TimestampQueryTests, ManyWriteTimestampDistinctQuerySets) {
+ constexpr uint32_t kQueryCount = 100;
+ // Write timestamp with a different query sets many times
+ for (uint32_t i = 0; i < kQueryCount; ++i) {
+ wgpu::QuerySet querySet = CreateQuerySetForTimestamp(1);
+
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ encoder.WriteTimestamp(querySet, 0);
+ wgpu::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+
+ // Destroy the query set so we don't OOM.
+ querySet.Destroy();
+ // Make sure the queue is idle so the query set is definitely destroyed.
+ WaitForAllOperations();
+ }
+}
+
class TimestampQueryInsidePassesTests : public TimestampQueryTests {
protected:
void SetUp() override {