Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save devshgraphicsprogramming/d966f2454dd77660a05896d1fd5691ed to your computer and use it in GitHub Desktop.
Save devshgraphicsprogramming/d966f2454dd77660a05896d1fd5691ed to your computer and use it in GitHub Desktop.
Garbage Collection, fencing, etc. Without Separate Memory Arenas [EARLY PROTOTYPE]
template <class T>
class STLCompatibleGPUAllocator : public irr::core::AllocatorTrivialBase<T>
{
public:
typedef size_t size_type;
typedef T* pointer;
template< class U> struct rebind { typedef STLCompatibleGPUAllocator<U> other; };
STLCompatibleGPUAllocator() {}
virtual ~STLCompatibleGPUAllocator() {}
template<typename U>
STLCompatibleGPUAllocator(const STLCompatibleGPUAllocator<U>& other) {}
template<typename U>
STLCompatibleGPUAllocator(STLCompatibleGPUAllocator<U>&& other) {}
T* allocate(size_type n, const void* hint=nullptr) noexcept;
void deallocate(T* p, size_type n) noexcept;
template<typename U>
inline bool operator!=(const STLCompatibleGPUAllocator<U>& other) const noexcept
{
return false;
}
template<typename U>
inline bool operator==(const STLCompatibleGPUAllocator<U>& other) const noexcept
{
return true;
}
// a little extra for copying contents between this allocator's memory and other buffer
inline void copyToBuffer(video::IGPUBuffer* outBuff, size_t offset, void* dataPtr, size_t dataSize) noexcept;
};
template<typename T>
inline T* STLCompatibleGPUAllocator<T>::allocate(size_type n, const void* hint) noexcept
{
auto actualAllocatorPointer = GLOBAL_READ_WRITE_STREAMING_BUFFER; // of type video::StreamingTransientDataBufferMT<>
uint32_t addr = video::StreamingTransientDataBufferMT<>::invalid_address;
const uint32_t bytes = n*sizeof(T);
const uint32_t alignment = 64u; // for teh lulz
const bool isMainThread = true; // for now, TODO
while (actualAllocatorPointer->multi_alloc(std::chrono::microseconds(1u),1u,&addr,&bytes,&alignment))
{
std::this_thread::yield();
}
return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(actualAllocatorPointer->getBufferPointer())+addr);
}
template<typename T>
inline void STLCompatibleGPUAllocator<T>::deallocate(T* p, size_type n) noexcept
{
auto actualAllocatorPointer = GLOBAL_READ_WRITE_STREAMING_BUFFER; // of type video::StreamingTransientDataBufferMT<>
uint32_t addr = reinterpret_cast<uint8_t*>(p)-reinterpret_cast<uint8_t*>(actualAllocatorPointer->getBufferPointer());
const uint32_t bytes = n*sizeof(T);
actualAllocatorPointer->multi_free(1u,&addr,&bytes); // no fence placed unfortunately
}
template<typename T>
inline void STLCompatibleGPUAllocator<T>::copyToBuffer(video::IGPUBuffer* outBuff, size_t offset, void* dataPtr, size_t dataSize) noexcept
{
auto actualAllocatorPointer = GLOBAL_READ_WRITE_STREAMING_BUFFER; // of type video::StreamingTransientDataBufferMT<>
uint32_t addr = reinterpret_cast<uint8_t*>(dataPtr)-reinterpret_cast<uint8_t*>(actualAllocatorPointer->getBufferPointer());
#ifdef _IRR_DEBUG
assert(addr<actualAllocatorPointer->getBuffer()->getSize());
#endif // _IRR_DEBUG
if (actualAllocatorPointer->needsManualFlushOrInvalidate())
gDriver->flushMappedMemoryRanges({{actualAllocatorPointer->getBuffer()->getBoundMemory(),addr,dataSize}});
gDriver->copyBuffer(actualAllocatorPointer->getBuffer(),outBuff,addr,offset,dataSize);
}
template<typename T>
class VectorFreeFunctor
{
public:
typedef core::vector<T,STLCompatibleGPUAllocator<uint32_t>*> VectorType;
VectorFreeFunctor(VectorType&& inVec) : vecToDelete(std::forward<VectorType>(inVec))
{
}
VectorFreeFunctor(const VectorFreeFunctor& other) = delete;
VectorFreeFunctor(VectorFreeFunctor&& other)
{
this->operator=(std::forward<VectorFreeFunctor>(other));
}
VectorFreeFunctor& operator=(const VectorFreeFunctor& other) = delete;
inline VectorFreeFunctor& operator=(VectorFreeFunctor&& other)
{
std::swap(vecToDelete,other.vecToDelete);
return *this;
}
inline bool operator()(uint32_t& unallocatedSize)
{
if (unallocatedSize==0u)
return;
if (!vecToDelete)
continue;
size_t capacity = vecToDelete->capacity()*sizeof(VectorType);
if (unallocatedSize<=capacity)
{
unallocatedSize = 0u;
break;
}
unallocatedSize -= capacity;
operator()();
return unallocatedSize==0u;
}
inline void operator()()
{
delete vecToDelete;
}
private:
VectorType* vecToDelete;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment