Skip to content

Commit cc54740

Browse files
committed
Add sub-allocated descriptor set header
1 parent f3ee9c0 commit cc54740

File tree

3 files changed

+121
-2
lines changed

3 files changed

+121
-2
lines changed

include/nbl/core/alloc/address_allocator_traits.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ namespace nbl::core
5353
}
5454
}
5555

56+
static inline void multi_alloc_addr(AddressAlloc& alloc, uint32_t count, size_type* outAddresses, const size_type* bytes,
57+
const size_type alignment, const size_type* hint=nullptr) noexcept
58+
{
59+
for (uint32_t i=0; i<count; i++)
60+
{
61+
if (outAddresses[i]!=AddressAlloc::invalid_address)
62+
continue;
63+
64+
outAddresses[i] = alloc.alloc_addr(bytes[i],alignment,hint ? hint[i]:0ull);
65+
}
66+
}
67+
5668
static inline void multi_free_addr(AddressAlloc& alloc, uint32_t count, const size_type* addr, const size_type* bytes) noexcept
5769
{
5870
for (uint32_t i=0; i<count; i++)
@@ -186,6 +198,14 @@ namespace nbl::core
186198
alloc,std::min(count-i,maxMultiOps),outAddresses+i,bytes+i,alignment+i,hint ? (hint+i):nullptr);
187199
}
188200

201+
static inline void multi_alloc_addr(AddressAlloc& alloc, uint32_t count, size_type* outAddresses,
202+
const size_type* bytes, const size_type alignment, const size_type* hint=nullptr) noexcept
203+
{
204+
for (uint32_t i=0; i<count; i+=maxMultiOps)
205+
impl::address_allocator_traits_base<AddressAlloc,has_func_multi_alloc_addr<AddressAlloc>::value>::multi_alloc_addr(
206+
alloc,std::min(count-i,maxMultiOps),outAddresses+i,bytes+i,alignment,hint ? (hint+i):nullptr);
207+
}
208+
189209
static inline void multi_free_addr(AddressAlloc& alloc, uint32_t count, const size_type* addr, const size_type* bytes) noexcept
190210
{
191211
for (uint32_t i=0; i<count; i+=maxMultiOps)
@@ -244,4 +264,4 @@ namespace nbl::core
244264

245265
}
246266

247-
#endif
267+
#endif
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
5+
#ifndef _NBL_VIDEO_SUB_ALLOCATED_DESCRIPTOR_SET_H_
6+
#define _NBL_VIDEO_SUB_ALLOCATED_DESCRIPTOR_SET_H
7+
8+
#include "nbl/video/alloc/IBufferAllocator.h"
9+
10+
#include <type_traits>
11+
12+
namespace nbl::video
13+
{
14+
15+
class SubAllocatedDescriptorSet : public core::IReferenceCounted
16+
{
17+
public:
18+
// address allocator gives offsets
19+
// reserved allocator allocates memory to keep the address allocator state inside
20+
using AddressAllocator = core::GeneralpurposeAddressAllocator<uint32_t>;
21+
using ReservedAllocator = core::allocator<uint8_t>;
22+
using size_type = typename AddressAllocator::size_type;
23+
using value_type = typename AddressAllocator::size_type;
24+
static constexpr value_type invalid_value = AddressAllocator::invalid_address;
25+
26+
protected:
27+
struct SubAllocDescriptorSetRange {
28+
video::IGPUDescriptorSetLayout::SBinding binding;
29+
std::shared_ptr<AddressAllocator> addressAllocator;
30+
std::shared_ptr<ReservedAllocator> reservedAllocator;
31+
size_t reservedSize;
32+
};
33+
std::vector<SubAllocDescriptorSetRange> m_allocatableRanges = {};
34+
35+
36+
public:
37+
// constructors
38+
template<typename... Args>
39+
inline SubAllocatedDescriptorSet(const std::span<const video::IGPUDescriptorSetLayout::SBinding> bindings,
40+
const value_type maxAllocatableAlignment, Args&&... args)
41+
{
42+
m_allocatableRanges.reserve(bindings.size());
43+
44+
for (auto& binding : bindings)
45+
{
46+
SubAllocDescriptorSetRange range;
47+
range.binding = binding;
48+
range.reservedSize = 0;
49+
// Only bindings with these flags will be allocatable
50+
if (binding.createFlags.hasFlags(core::bitflag(IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_UPDATE_AFTER_BIND_BIT)
51+
| IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_UPDATE_UNUSED_WHILE_PENDING_BIT
52+
| IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_PARTIALLY_BOUND_BIT))
53+
{
54+
range.reservedSize = AddressAllocator::reserved_size(maxAllocatableAlignment, static_cast<size_type>(binding.count), args...);
55+
range.reservedAllocator = std::shared_ptr<ReservedAllocator>(new ReservedAllocator());
56+
range.addressAllocator = std::shared_ptr<AddressAllocator>(new AddressAllocator(
57+
range.reservedAllocator->allocate(range.reservedSize, _NBL_SIMD_ALIGNMENT),
58+
static_cast<size_type>(0), 0u, maxAllocatableAlignment, static_cast<size_type>(binding.count), std::forward<Args>(args)...
59+
));
60+
}
61+
m_allocatableRanges.push_back(range);
62+
}
63+
64+
}
65+
66+
~SubAllocatedDescriptorSet()
67+
{
68+
for (uint32_t i = 0; i < m_allocatableRanges.size(); i++)
69+
{
70+
auto& range = m_allocatableRanges[i];
71+
if (range.reservedSize == 0)
72+
continue;
73+
74+
auto ptr = reinterpret_cast<const uint8_t*>(core::address_allocator_traits<AddressAllocator>::getReservedSpacePtr(*range.addressAllocator));
75+
range.reservedAllocator->deallocate(const_cast<uint8_t*>(ptr), range.reservedSize);
76+
}
77+
}
78+
79+
// main methods
80+
81+
//! Warning `outAddresses` needs to be primed with `invalid_value` values, otherwise no allocation happens for elements not equal to `invalid_value`
82+
template<typename... Args>
83+
inline void multi_allocate(uint32_t binding, uint32_t count, value_type* outAddresses, const size_type* sizes, const Args&... args)
84+
{
85+
auto& range = m_allocatableRanges[binding];
86+
assert(range.reservedSize); // Check if this binding has an allocator
87+
core::address_allocator_traits<AddressAllocator>::multi_alloc_addr(*range.addressAllocator, count, outAddresses, sizes, 1, args...);
88+
}
89+
inline void multi_deallocate(uint32_t binding, uint32_t count, const size_type* addr, const size_type* sizes)
90+
{
91+
auto& range = m_allocatableRanges[binding];
92+
assert(range.reservedSize); // Check if this binding has an allocator
93+
core::address_allocator_traits<AddressAllocator>::multi_free_addr(*range.addressAllocator, count, addr, sizes);
94+
}
95+
};
96+
97+
}
98+
99+
#endif

0 commit comments

Comments
 (0)