Photon Editor Library 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
GraphicsMemoryBlock.ipp
Go to the documentation of this file.
1#pragma once
2
4
5#include <Common/assertion.h>
6#include <Common/math_basics.h>
7
8#include <utility>
9#include <memory>
10#include <type_traits>
11
12namespace ph::editor::ghi
13{
14
16{
17 return m_blockSizeInBytes;
18}
19
20inline std::size_t GraphicsMemoryBlock::numUsedBytes() const
21{
22 PH_ASSERT_GE(m_blockSizeInBytes, m_remainingBytesInBlock);
23 return m_blockSizeInBytes - m_remainingBytesInBlock;
24}
25
27{
28 return m_remainingBytesInBlock;
29}
30
32{
33 m_ptrInBlock = m_blockSource;
34 m_remainingBytesInBlock = m_blockSizeInBytes;
35}
36
37template<typename T, typename... Args>
38inline T* GraphicsMemoryBlock::make(Args&&... args)
39{
40 static_assert(std::is_trivially_destructible_v<T>);
41
42 // IOC of array of size 1
43 T* const storage = reinterpret_cast<T*>(allocRaw(sizeof(T), alignof(T)));
44 if(!storage)
45 {
46 return nullptr;
47 }
48
49 return std::construct_at(storage, std::forward<Args>(args)...);
50}
51
52template<typename T>
53inline TSpan<T> GraphicsMemoryBlock::makeArray(const std::size_t arraySize)
54{
55 // To not violate [basic.life] section 8.3 later
56 // (https://timsong-cpp.github.io/cppwp/basic.life#8.3)
57 using NonConstT = std::remove_const_t<T>;
58
59 static_assert(std::is_default_constructible_v<NonConstT>);
60 static_assert(std::is_trivially_destructible_v<NonConstT>);
61
62 // IOC of array of size `arraySize`
63 NonConstT* const storage = reinterpret_cast<NonConstT*>(
64 allocRaw(sizeof(NonConstT) * arraySize, alignof(NonConstT)));
65 if(!storage)
66 {
67 return {};
68 }
69
70 std::uninitialized_default_construct_n(storage, arraySize);
71
72 // Potentially do implicit non-const -> const conversion
73 return TSpan<NonConstT>(storage, arraySize);
74}
75
76inline std::byte* GraphicsMemoryBlock::allocRaw(
77 const std::size_t numBytes,
78 const std::size_t alignmentInBytes)
79{
80 PH_ASSERT(m_blockSource);
81 PH_ASSERT(math::is_power_of_2(alignmentInBytes));
82
83 void* ptr = m_ptrInBlock;
84 std::size_t availableBytes = m_remainingBytesInBlock;
85 void* alignedPtr = std::align(alignmentInBytes, numBytes, ptr, availableBytes);
86
87 // Return null if there is not enough space left
88 if(!alignedPtr)
89 {
90 return nullptr;
91 }
92
93 PH_ASSERT(alignedPtr);
94 PH_ASSERT_GE(availableBytes, numBytes);
95
96 // We have a successfully aligned allocation here, update block states
97
98 // `std::align()` only adjusts `ptr` to the aligned memory location
99 m_ptrInBlock = static_cast<std::byte*>(ptr) + numBytes;
100
101 // `std::align()` only decreases `availableBytes` by the number of bytes used for alignment
102 m_remainingBytesInBlock = availableBytes - numBytes;
103
104 return start_implicit_lifetime_as_array<std::byte>(alignedPtr, numBytes);
105}
106
107}// end namespace ph::editor::ghi
std::size_t numAllocatedBytes() const
Definition GraphicsMemoryBlock.ipp:15
T * make(Args &&... args)
Make an object of type T as if by calling its constructor with Args.
Definition GraphicsMemoryBlock.ipp:38
TSpan< T > makeArray(std::size_t arraySize)
Make an array of default constructed objects of type T.
Definition GraphicsMemoryBlock.ipp:53
std::size_t numUsedBytes() const
Definition GraphicsMemoryBlock.ipp:20
void clear()
Reset the usage of the block. All memory handed out are effectively deallocated/deleted after this ca...
Definition GraphicsMemoryBlock.ipp:31
std::size_t numRemainingBytes() const
Definition GraphicsMemoryBlock.ipp:26
Definition PlatformDisplay.h:13