From 3c4fddf3e3a23242dce031881fa319d01462e545 Mon Sep 17 00:00:00 2001 From: Austin Eng Date: Tue, 6 Dec 2022 02:25:23 +0000 Subject: [PATCH] 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 Reviewed-by: Loko Kung Kokoro: Kokoro --- src/dawn/native/metal/CommandBufferMTL.mm | 3 ++- src/dawn/tests/end2end/QueryTests.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/dawn/native/metal/CommandBufferMTL.mm b/src/dawn/native/metal/CommandBufferMTL.mm index 91aacbff92..f1f5131eba 100644 --- a/src/dawn/native/metal/CommandBufferMTL.mm +++ b/src/dawn/native/metal/CommandBufferMTL.mm @@ -334,7 +334,8 @@ void EncodeEmptyBlitEncoderForWriteTimestamp(Device* device, 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 f8cf53c27e..9d4ec5a175 100644 --- a/src/dawn/tests/end2end/QueryTests.cpp +++ b/src/dawn/tests/end2end/QueryTests.cpp @@ -1078,6 +1078,26 @@ TEST_P(TimestampQueryTests, ResolveTwiceToSameBuffer) { 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 {