From 233ce73c50b71dc7d9b711342cbfea3b28902023 Mon Sep 17 00:00:00 2001 From: Austin Eng Date: Wed, 5 Jun 2019 16:16:37 +0000 Subject: [PATCH] Add Create/ReleaseStagingBuffer to DynamicUploader StagingBuffers need to be created and explicitly released outside of the RingBuffer for CreateBufferMapped since the staging buffer must live until the Buffer is Unmapped or Destroyed. This patch adds methods to the DynamicUploaded for creating and tracking the release of StagingBuffers. This patch also fixes SerialQueue for non-copy-constructible types. Bug: dawn:7 Change-Id: I582c4d9cf452f808a8a7ab4164ff833087619a18 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/7720 Commit-Queue: Austin Eng Reviewed-by: Corentin Wallez --- src/common/SerialQueue.h | 12 ++++++------ src/dawn_native/DynamicUploader.cpp | 14 ++++++++++++++ src/dawn_native/DynamicUploader.h | 10 +++++++++- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/common/SerialQueue.h b/src/common/SerialQueue.h index f5654a9871..24303c7f60 100644 --- a/src/common/SerialQueue.h +++ b/src/common/SerialQueue.h @@ -54,9 +54,9 @@ void SerialQueue::Enqueue(const T& value, Serial serial) { DAWN_ASSERT(this->Empty() || this->mStorage.back().first <= serial); if (this->Empty() || this->mStorage.back().first < serial) { - this->mStorage.emplace_back(SerialPair(serial, {})); + this->mStorage.emplace_back(serial, std::vector{}); } - this->mStorage.back().second.emplace_back(value); + this->mStorage.back().second.push_back(value); } template @@ -64,23 +64,23 @@ void SerialQueue::Enqueue(T&& value, Serial serial) { DAWN_ASSERT(this->Empty() || this->mStorage.back().first <= serial); if (this->Empty() || this->mStorage.back().first < serial) { - this->mStorage.emplace_back(SerialPair(serial, {})); + this->mStorage.emplace_back(serial, std::vector{}); } - this->mStorage.back().second.emplace_back(value); + this->mStorage.back().second.push_back(std::move(value)); } template void SerialQueue::Enqueue(const std::vector& values, Serial serial) { DAWN_ASSERT(values.size() > 0); DAWN_ASSERT(this->Empty() || this->mStorage.back().first <= serial); - this->mStorage.emplace_back(SerialPair(serial, {values})); + this->mStorage.emplace_back(serial, values); } template void SerialQueue::Enqueue(std::vector&& values, Serial serial) { DAWN_ASSERT(values.size() > 0); DAWN_ASSERT(this->Empty() || this->mStorage.back().first <= serial); - this->mStorage.emplace_back(SerialPair(serial, {values})); + this->mStorage.emplace_back(serial, values); } #endif // COMMON_SERIALQUEUE_H_ diff --git a/src/dawn_native/DynamicUploader.cpp b/src/dawn_native/DynamicUploader.cpp index b5310e1bad..d5c04504fe 100644 --- a/src/dawn_native/DynamicUploader.cpp +++ b/src/dawn_native/DynamicUploader.cpp @@ -21,6 +21,19 @@ namespace dawn_native { DynamicUploader::DynamicUploader(DeviceBase* device) : mDevice(device) { } + ResultOrError> DynamicUploader::CreateStagingBuffer( + size_t size) { + std::unique_ptr stagingBuffer; + DAWN_TRY_ASSIGN(stagingBuffer, mDevice->CreateStagingBuffer(size)); + DAWN_TRY(stagingBuffer->Initialize()); + return stagingBuffer; + } + + void DynamicUploader::ReleaseStagingBuffer(std::unique_ptr stagingBuffer) { + mReleasedStagingBuffers.Enqueue(std::move(stagingBuffer), + mDevice->GetPendingCommandSerial()); + } + MaybeError DynamicUploader::CreateAndAppendBuffer(size_t size) { std::unique_ptr ringBuffer = std::make_unique(mDevice, size); DAWN_TRY(ringBuffer->Initialize()); @@ -69,6 +82,7 @@ namespace dawn_native { mRingBuffers.erase(mRingBuffers.begin() + i); } } + mReleasedStagingBuffers.ClearUpTo(lastCompletedSerial); } RingBuffer* DynamicUploader::GetLargestBuffer() { diff --git a/src/dawn_native/DynamicUploader.h b/src/dawn_native/DynamicUploader.h index ef4990804b..5e4d079602 100644 --- a/src/dawn_native/DynamicUploader.h +++ b/src/dawn_native/DynamicUploader.h @@ -27,6 +27,13 @@ namespace dawn_native { DynamicUploader(DeviceBase* device); ~DynamicUploader() = default; + // We add functions to Create/Release StagingBuffers to the DynamicUploader as there's + // currently no place to track the allocated staging buffers such that they're freed after + // pending coommands are finished. This should be changed when better resource allocation is + // implemented. + ResultOrError> CreateStagingBuffer(size_t size); + void ReleaseStagingBuffer(std::unique_ptr stagingBuffer); + ResultOrError Allocate(uint32_t requiredSize, uint32_t alignment); void Tick(Serial lastCompletedSerial); @@ -41,8 +48,9 @@ namespace dawn_native { static constexpr size_t kBaseUploadBufferSize = 64000; std::vector> mRingBuffers; + SerialQueue> mReleasedStagingBuffers; DeviceBase* mDevice; }; } // namespace dawn_native -#endif // DAWNNATIVE_DYNAMICUPLOADER_H_ \ No newline at end of file +#endif // DAWNNATIVE_DYNAMICUPLOADER_H_