-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start adding a Metal readback pool to support GPU downloads
- Loading branch information
Showing
8 changed files
with
135 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#include <Config.h> | ||
#if ENABLE_METAL | ||
|
||
#include <Metal/Metal.h> | ||
#include "MetalReadbackBufferPool.h" | ||
#include "MetalDevice.h" | ||
#include "MetalResources.h" | ||
|
||
namespace coalpy | ||
{ | ||
namespace render | ||
{ | ||
|
||
enum | ||
{ | ||
InitialBufferPoolSize = 1024 * 1024 * 5 //5 megabytes of initial size | ||
}; | ||
|
||
bool MetalReadbackBufferPool::createNewHeap(size_t size) | ||
{ | ||
short heapIndex = (short)m_heaps.size(); | ||
m_heaps.emplace_back(); | ||
HeapState& heap = m_heaps.back(); | ||
|
||
BufferDesc bufferDesc; | ||
bufferDesc.type = BufferType::Standard; | ||
bufferDesc.format = Format::RGBA_8_UINT; | ||
bufferDesc.elementCount = size; | ||
bufferDesc.memFlags = (MemFlags)0; | ||
ResourceSpecialFlags readbackFlags = ResourceSpecialFlag_CpuReadback; | ||
BufferResult result = m_device.resources().createBuffer(bufferDesc, readbackFlags); | ||
if (!result.success()) | ||
return false; | ||
|
||
heap.buffer = result; | ||
heap.largestSize = size; | ||
MetalReadbackMemBlock memBlock; | ||
memBlock.size = size; | ||
memBlock.offset = 0; | ||
memBlock.buffer = result; | ||
memBlock.allocationId = m_nextAllocId++; | ||
memBlock.heapIndex = heapIndex; | ||
|
||
return true; | ||
} | ||
|
||
MetalReadbackBufferPool::MetalReadbackBufferPool(MetalDevice& device) | ||
: m_device(device) | ||
{ | ||
bool success = createNewHeap(InitialBufferPoolSize); | ||
CPY_ASSERT_MSG(success, "Could not allocate heap."); | ||
m_nextHeapSize = 2 * InitialBufferPoolSize; | ||
} | ||
|
||
MetalReadbackBufferPool::~MetalReadbackBufferPool() | ||
{ | ||
for (auto& h : m_heaps) | ||
{ | ||
m_device.resources().release(h.buffer); | ||
CPY_ASSERT_MSG(h.freeBlocks.size() == 1, "Warning: non freed heap elements found. Buffer pool has some memory blocks that have not been freed."); | ||
} | ||
m_heaps.clear(); | ||
} | ||
|
||
} | ||
} | ||
#endif // ENABLE_METAL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#pragma once | ||
|
||
#include <vector> | ||
#include <coalpy.render/Resources.h> | ||
|
||
@protocol MTLBuffer; | ||
|
||
namespace coalpy | ||
{ | ||
namespace render | ||
{ | ||
|
||
class MetalDevice; | ||
class MetalResource; | ||
|
||
struct MetalReadbackMemBlock | ||
{ | ||
size_t size = 0ull; | ||
size_t offset = 0ull; | ||
Buffer buffer = {}; | ||
short allocationId = 0; | ||
short heapIndex = 0; | ||
|
||
bool valid() const { return buffer.valid(); } | ||
}; | ||
|
||
class MetalReadbackBufferPool | ||
{ | ||
public: | ||
MetalReadbackBufferPool(MetalDevice& device); | ||
~MetalReadbackBufferPool(); | ||
|
||
MetalReadbackMemBlock allocate(size_t size); | ||
void free(const MetalReadbackMemBlock& block); | ||
|
||
private: | ||
MetalDevice& m_device; | ||
|
||
bool createNewHeap(size_t size); | ||
|
||
struct HeapState | ||
{ | ||
Buffer buffer; | ||
std::vector<MetalReadbackMemBlock> freeBlocks; | ||
size_t largestSize = 0ull; | ||
}; | ||
|
||
std::vector<HeapState> m_heaps; | ||
size_t m_nextHeapSize = 0; | ||
short m_nextAllocId = 0; | ||
bool m_isReadback; | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters