Commit 2dff0297 authored by Lukas Tietze's avatar Lukas Tietze

Memory-Klasse

parent 9dc40d70
#pragma once
#include "VkUtil/Memory/MemoryAllocation.hpp"
#include "VkUtil/Memory/MappedMemory.hpp"
#include "GlfwAndVulkan.hpp"
#include <map>
namespace lib
{
/**
* @brief Forward-Declaration für CgContext.
*/
class CgContext;
/**
* @brief Stellt einen Block Speicher dar. Dieser Block kann für einen oder mehrere Puffer genutzt werden,
* stellt jedoch keine dynamische Allozierung bereit. Die Klasse arbeitet nach dem RAII-Prinzip, der
* Konstruktor alloziert Speicher, der Destruktor gibt diesen Speicher wieder frei.
*/
class Memory
{
private:
/**
* @brief Die gesamte Größe des Speicherblocks.
*/
vk::DeviceSize totalSize{0};
/**
* @brief Die Handle zum Speicher.
*/
vk::DeviceMemory handle{nullptr};
/**
* @brief Das Ende des derzeit allozierten Bereichs.
*/
vk::DeviceSize allocationEnd{0};
/**
* @brief Der zu nutzende CgContext.
*/
CgContext *context{nullptr};
public:
/**
* @brief Initialisiert eine neue Instanz der Memory Klasse und alloziert Speicher.
*
* @param context Der zu nutzende CgContext
* @param size Die Größe des angeforderten Speichers.
* @param type Der Typ des Speichers.
*/
Memory(CgContext *context, vk::DeviceSize size, uint32_t type);
/**
* @brief Gelöschter Copy-Constructor.
*/
Memory(const Memory &copy) = delete;
/**
* @brief Move-Constructor.
*
* @param move Das Objekt von dem Ressourcen bewegt werden sollen.
*/
Memory(Memory &&move);
/**
* @brief Zerstört das Memory Objekt und gibt den allozierten Speicher frei.
*/
~Memory();
/**
* @brief Ruft den gesamten verfügbaren Speicher ab.
*
* @return MemoryAllocation Der Bereich des allozierten Speichers.
*/
MemoryAllocation Acquire();
/**
* @brief Ruft einen Teil des verfügbaren Speichers ab.
*
* @return MemoryAllocation Der Bereich des allozierten Speichers.
*/
MemoryAllocation Acquire(vk::DeviceSize size);
/**
* @brief Mapped den gesamten Speicher.
*
* @return MappedMemory Der Gemappedte Speicher.
*/
MappedMemory Map() const;
/**
* @brief Mapped einen Teil des Speichers.
*
* @return MappedMemory Der Gemappedte Speicher.
*/
MappedMemory Map(vk::DeviceSize offset, vk::DeviceSize size) const;
/**
* @brief Gelöschter Copy-Assignment-Operator.
*/
Memory &operator=(const Memory &move) = delete;
/**
* @brief Move-Assignment-Operator.
*
* @param move Das Objekt von dem Ressourcen bewegt werden sollen.
*/
Memory &operator=(Memory &&move);
friend void swap(Memory &a, Memory &b);
};
/**
* @brief Tauscht die beiden Memory-Instanzen.
*
* @param a Das erste Objekt.
* @param b Das zweite Objekt.
*/
void swap(Memory &a, Memory &b);
} // namespace lib
#pragma once
#include "VkUtil/Memory/MappedMemory.hpp"
#include "GlfwAndVulkan.hpp"
namespace lib
{
/**
* @brief Stell ein Stück allozierten Speicher dar.
*/
struct MemoryAllocation
{
MemoryAllocation() = default;
inline MemoryAllocation(vk::DeviceMemory memory,
vk::DeviceSize offset,
vk::DeviceSize size)
: memory(memory),
offset(offset),
size(size)
{
}
vk::DeviceMemory memory{nullptr};
vk::DeviceSize offset{0};
vk::DeviceSize size{0};
};
} // namespace lib
......@@ -5,9 +5,19 @@
namespace lib
{
/**
* @brief Ein Ausnahme, die erzeugt wird wenn ein Memory-Objekt keinen Speicher mehr verteilen kann.
*/
class OutOfMemoryException final : public lib::ExceptionBase
{
public:
OutOfMemoryException(vk::DeviceSize requested, vk::DeviceSize available, vk::DeviceSize available);
/**
* @brief Initialisiert eine neue Instanz der Out Of Memory Exception Klasse.
*
* @param requested Der angeforderte Speicher in Byte.
* @param available Der verfügbare Speicher in Byte.
* @param total Der gesamte Speicher in Byte.
*/
OutOfMemoryException(vk::DeviceSize requested, vk::DeviceSize available, vk::DeviceSize total);
};
} // namespace lib
#include <algorithm>
#include "Core/CgContext.hpp"
#include "VkUtil/Memory/Memory.hpp"
#include "VkUtil/Memory/OutOfMemoryException.hpp"
lib::Memory::Memory(CgContext *context, vk::DeviceSize size, uint32_t type)
: context(context),
totalSize(size)
{
vk::MemoryAllocateInfo info;
info.allocationSize = size;
info.memoryTypeIndex = type;
this->handle = this->context->GetLogicalDevice().allocateMemory(info);
}
lib::Memory::Memory(Memory &&move)
{
swap(*this, move);
}
lib::Memory::~Memory()
{
if (this->handle)
{
this->context->GetLogicalDevice().freeMemory(this->handle);
}
}
lib::MemoryAllocation lib::Memory::Acquire()
{
return this->Acquire(this->totalSize);
}
lib::MemoryAllocation lib::Memory::Acquire(vk::DeviceSize size)
{
if (this->allocationEnd + size > this->totalSize)
{
throw lib::OutOfMemoryException(size, this->totalSize - this->allocationEnd, this->totalSize);
}
MemoryAllocation res{
this->handle,
this->allocationEnd,
size};
this->allocationEnd += size;
return res;
}
lib::MappedMemory lib::Memory::Map() const
{
return this->Map(0, this->totalSize);
}
lib::MappedMemory lib::Memory::Map(vk::DeviceSize offset, vk::DeviceSize size) const
{
return MappedMemory(this->context, this->handle, offset, size);
}
lib::Memory &lib::Memory::operator=(Memory &&move)
{
if (this != &move)
{
swap(*this, move);
}
return *this;
}
void lib::swap(Memory &a, Memory &b)
{
using std::swap;
swap(a.allocationEnd, b.allocationEnd);
swap(a.context, b.context);
swap(a.handle, b.handle);
swap(a.totalSize, b.totalSize);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment