1 // 2 // Copyright 2022 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // AllocatorHelperRing: 7 // Implements the ring buffer allocator helpers used in the command buffers. 8 // 9 10 #include "libANGLE/renderer/vulkan/AllocatorHelperRing.h" 11 #include "libANGLE/renderer/vulkan/SecondaryCommandBuffer.h" 12 13 namespace rx 14 { 15 namespace vk 16 { 17 resetAllocator()18void SharedCommandBlockAllocator::resetAllocator() 19 { 20 ASSERT(!mAllocator || !mAllocator->isShared()); 21 22 if (mAllocSharedCP) 23 { 24 mAllocSharedCP->releaseAndUpdate(&mAllocReleaseCP); 25 mAllocSharedCP = nullptr; 26 } 27 28 ASSERT(!mAllocSharedCP && !mAllocReleaseCP.valid()); 29 } 30 attachAllocator(SharedCommandMemoryAllocator * allocator)31void SharedCommandBlockAllocator::attachAllocator(SharedCommandMemoryAllocator *allocator) 32 { 33 ASSERT(allocator); 34 ASSERT(!mAllocator); 35 mAllocator = allocator; 36 if (mAllocator->isShared()) 37 { 38 mAllocator->releaseToSharedCP(); 39 } 40 } 41 detachAllocator(bool isCommandBufferEmpty)42SharedCommandMemoryAllocator *SharedCommandBlockAllocator::detachAllocator( 43 bool isCommandBufferEmpty) 44 { 45 ASSERT(mAllocator); 46 if (!isCommandBufferEmpty) 47 { 48 // Must call reset() after detach from non-empty command buffer (OK to have an empty RP) 49 ASSERT(!mAllocSharedCP && !mAllocReleaseCP.valid()); 50 mAllocSharedCP = mAllocator->acquireSharedCP(); 51 mAllocReleaseCP = mAllocator->get().getReleaseCheckPoint(); 52 } 53 SharedCommandMemoryAllocator *result = mAllocator; 54 mAllocator = nullptr; 55 return result; 56 } 57 attachAllocator(SharedCommandMemoryAllocator * source)58void SharedCommandBlockPool::attachAllocator(SharedCommandMemoryAllocator *source) 59 { 60 ASSERT(source); 61 RingBufferAllocator &sourceIn = source->get(); 62 63 ASSERT(sourceIn.valid()); 64 ASSERT(mCommandBuffer->hasEmptyCommands()); 65 ASSERT(mLastCommandBlock == nullptr); 66 ASSERT(mFinishedCommandSize == 0); 67 ASSERT(!mAllocator.valid()); 68 mAllocator = std::move(sourceIn); 69 mAllocator.setFragmentReserve(kCommandHeaderSize); 70 pushNewCommandBlock(mAllocator.allocate(0)); 71 mAllocator.setListener(this); 72 } 73 detachAllocator(SharedCommandMemoryAllocator * destination)74void SharedCommandBlockPool::detachAllocator(SharedCommandMemoryAllocator *destination) 75 { 76 ASSERT(destination); 77 RingBufferAllocator &destinationOut = destination->get(); 78 ASSERT(!destinationOut.valid()); 79 80 ASSERT(mAllocator.valid()); 81 mAllocator.setListener(nullptr); 82 finishLastCommandBlock(); 83 if (mFinishedCommandSize == 0) 84 { 85 mCommandBuffer->clearCommands(); 86 } 87 else 88 { 89 mAllocator.setFragmentReserve(0); 90 (void)mAllocator.allocate(sizeof(kCommandHeaderSize)); 91 } 92 destinationOut = std::move(mAllocator); 93 } 94 pushNewCommandBlock(uint8_t * block)95void SharedCommandBlockPool::pushNewCommandBlock(uint8_t *block) 96 { 97 mLastCommandBlock = block; 98 mCommandBuffer->pushToCommands(block); 99 } 100 finishLastCommandBlock()101void SharedCommandBlockPool::finishLastCommandBlock() 102 { 103 mFinishedCommandSize = getCommandSize(); 104 terminateLastCommandBlock(); 105 mLastCommandBlock = nullptr; 106 } 107 onRingBufferNewFragment()108void SharedCommandBlockPool::onRingBufferNewFragment() 109 { 110 pushNewCommandBlock(mAllocator.getPointer()); 111 } 112 onRingBufferFragmentEnd()113void SharedCommandBlockPool::onRingBufferFragmentEnd() 114 { 115 finishLastCommandBlock(); 116 } 117 getMemoryUsageStats(size_t * usedMemoryOut,size_t * allocatedMemoryOut) const118void SharedCommandBlockPool::getMemoryUsageStats(size_t *usedMemoryOut, 119 size_t *allocatedMemoryOut) const 120 { 121 *usedMemoryOut = getCommandSize(); 122 *allocatedMemoryOut = getCommandSize(); 123 } 124 125 } // namespace vk 126 } // namespace rx 127