Lluvia
Buffer.h
Go to the documentation of this file.
1 
8 #ifndef LLUVIA_CORE_BUFFER_BUFFER_H_
9 #define LLUVIA_CORE_BUFFER_BUFFER_H_
10 
11 #include "lluvia/core/Object.h"
13 #include "lluvia/core/error.h"
16 
18 
19 #include <array>
20 #include <cstdint>
21 #include <iostream>
22 #include <memory>
23 #include <string>
24 #include <tuple>
25 #include <type_traits>
26 #include <vector>
27 
28 namespace ll {
29 
30 class Buffer;
31 class CommandBuffer;
32 class ComputeGraph;
33 class ComputeNode;
34 class Session;
35 
57 class Buffer : public Object {
58 
59 public:
60  Buffer() = delete;
61  Buffer(const Buffer& b) = delete;
62  Buffer(Buffer&& b) = delete;
63 
65 
66  Buffer& operator=(const Buffer& buffer) = delete;
67  Buffer& operator=(Buffer&& buffer) = delete;
68 
69  ll::ObjectType getType() const noexcept override;
70 
77 
83  const std::shared_ptr<ll::Memory>& getMemory() const noexcept;
84 
95  uint64_t getSize() const noexcept;
96 
105  ll::BufferUsageFlags getUsageFlags() const noexcept;
106 
114  uint32_t getUsageFlagsUnsafe() const noexcept;
115 
125  bool isMappable() const noexcept;
126 
131 
132  template <typename T>
133  void operator()([[maybe_unused]] T* ptr) const
134  {
135  buffer->unmap();
136  }
137 
139  };
140 
188  template <typename T>
189  std::unique_ptr<T, ll::Buffer::BufferMapDeleter> map()
190  {
191 
192  if (!m_memory->isPageMappable(m_allocInfo.page)) {
193  throw std::system_error(createErrorCode(ll::ErrorCode::MemoryMapFailed), "memory page " + std::to_string(m_allocInfo.page) + " is currently mapped by another object or this memory cannot be mapped");
194  }
195 
196  // remove array extend from T if present
197  typedef typename std::conditional<std::is_array<T>::value, typename std::remove_all_extents<T>::type, T>::type baseType;
198 
199  auto ptr = m_memory->mapBuffer(*this);
200 
201  auto deleter = ll::Buffer::BufferMapDeleter {};
202  deleter.buffer = this;
203 
204  return std::unique_ptr<T, ll::Buffer::BufferMapDeleter> {static_cast<baseType*>(ptr), deleter};
205  }
206 
207  template <typename T>
208  void mapAndSet(T&& obj)
209  {
210 
211  const auto objSize = sizeof(obj);
212  if (objSize > getSize()) {
213  ll::throwSystemError(ll::ErrorCode::MemoryMapFailed, "size of input object (" + std::to_string(objSize) + " bytes) is greater than size of buffer (" + std::to_string(getSize()) + " bytes)");
214  }
215 
216  auto ptr = map<std::remove_const_t<std::remove_reference_t<T>>>();
217 
218  std::memcpy(static_cast<void*>(ptr.get()), &obj, objSize);
219  }
220 
221  template <typename T>
222  void mapAndSetFromVector(const std::vector<T>& vec)
223  {
224 
225  const auto vecSize = vec.size() * sizeof(T);
226  if (vecSize > getSize()) {
227  ll::throwSystemError(ll::ErrorCode::MemoryMapFailed, "size of input vector (" + std::to_string(vecSize) + " bytes) is greater than size of buffer (" + std::to_string(getSize()) + " bytes)");
228  }
229 
230  auto ptr = map<std::remove_const_t<std::remove_reference_t<T>>>();
231 
232  std::memcpy(static_cast<void*>(ptr.get()), vec.data(), vecSize);
233  }
234 
235 private:
236  Buffer(const vk::Buffer vkBuffer, const ll::BufferUsageFlags usageFlags,
237  const std::shared_ptr<ll::Memory>& memory, const ll::MemoryAllocationInfo& allocInfo,
238  const uint64_t requestedSize);
239 
240  void unmap();
241 
242  vk::Buffer m_vkBuffer;
243  ll::BufferUsageFlags m_usageFlags;
244 
245  ll::MemoryAllocationInfo m_allocInfo;
246 
247  // the size requested for the buffer. It can
248  // be less than allocInfo.size due to alignment
249  // and size requirements for the given memory.
250  uint64_t m_requestedSize;
251 
252  // Shared pointer to the memory this buffer was created from
253  // This will keep the memory alive until this buffer is deleted
254  // avoiding reference to a corrupted memory location.
255  std::shared_ptr<ll::Memory> m_memory;
256 
257  friend class ll::CommandBuffer;
258  friend class ll::ComputeGraph;
259  friend class ll::ComputeNode;
260  friend class ll::Memory;
261  friend class ll::Session;
262 };
263 
264 } // namespace ll
265 
266 #endif // LLUVIA_CORE_BUFFER_BUFFER_H_
Structures and methods for storing memory allocation information.
Memory class.
Object class and related enums.
Objects to manage raw portions of allocated memory.
Definition: Buffer.h:57
uint32_t getUsageFlagsUnsafe() const noexcept
Gets the usage flags casted to an integer type.
ll::MemoryAllocationInfo getAllocationInfo() const noexcept
Gets the allocation information.
Buffer & operator=(Buffer &&buffer)=delete
Buffer(Buffer &&b)=delete
ll::BufferUsageFlags getUsageFlags() const noexcept
Gets the Vulkan buffer usage flags.
Buffer()=delete
friend class ll::ComputeGraph
Definition: Buffer.h:258
Buffer(const Buffer &b)=delete
ll::ObjectType getType() const noexcept override
Gets the object type.
std::unique_ptr< T, ll::Buffer::BufferMapDeleter > map()
Maps the memory content of this object to host-visible memory.
Definition: Buffer.h:189
void mapAndSetFromVector(const std::vector< T > &vec)
Definition: Buffer.h:222
bool isMappable() const noexcept
Determines if this buffer is mappable to host-visible memory.
const std::shared_ptr< ll::Memory > & getMemory() const noexcept
Gets the memory this buffer was allocated from.
uint64_t getSize() const noexcept
Gets the size of the buffer in bytes.
void mapAndSet(T &&obj)
Definition: Buffer.h:208
Buffer & operator=(const Buffer &buffer)=delete
Class for command buffer.
Definition: CommandBuffer.h:63
Class representing compute nodes.
Definition: ComputeNode.h:38
Class to manage allocation of objects into a specific type of memory.
Definition: Memory.h:92
Base class for all types that can be used in computer shaders.
Definition: Object.h:94
Class that contains all the state required to run compute operations on a compute device.
Definition: Session.h:51
error related classes and methods.
Definition: Buffer.h:28
ObjectType
Object types.
Definition: Object.h:29
void throwSystemError(ll::ErrorCode errorCode, T &&msg)
Throws a std::system_error exception with error code and message.
Definition: error.h:173
std::error_code createErrorCode(ll::ErrorCode errorCode)
Creates an error code.
Definition: error.h:138
Deleter for unmapping buffers from host memory.
Definition: Buffer.h:130
ll::Buffer * buffer
Definition: Buffer.h:138
void operator()([[maybe_unused]] T *ptr) const
Definition: Buffer.h:133
Structure to hold the allocation information of objects in memory.
Definition: MemoryAllocationInfo.h:19
uint32_t page
page number within memory
Definition: MemoryAllocationInfo.h:31