Skip to content

Commit ef4b779

Browse files
committed
WIP Suballocated descriptor set
1 parent b625153 commit ef4b779

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
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+
// address allocator gives offsets
16+
// reserved allocator allocates memory to keep the address allocator state inside
17+
template<class AddrAllocator, class ReservAllocator=core::allocator<uint8_t>>
18+
class SubAllocatedDescriptorSet : public core::IReferenceCounted
19+
{
20+
public:
21+
using AddressAllocator = AddrAllocator;
22+
using ReservedAllocator = ReservAllocator;
23+
using size_type = typename AddressAllocator::size_type;
24+
using value_type = typename AddressAllocator::size_type;
25+
static constexpr value_type invalid_value = AddressAllocator::invalid_address;
26+
27+
// constructors
28+
template<typename... Args>
29+
inline SubAllocatedDescriptorSet(const std::span<const video::IGPUDescriptorSetLayout::SBinding> bindings,
30+
ReservedAllocator&& _reservedAllocator, const value_type maxAllocatableAlignment, Args&&... args)
31+
{
32+
auto allocatableDescriptors = 0;
33+
m_allocatableRanges.reserve(bindings.size());
34+
35+
for (auto& binding : bindings)
36+
{
37+
SubAllocDescriptorSetRange range;
38+
range.offset = allocatableDescriptors;
39+
range.binding = binding;
40+
// Only bindings with these flags will be allocatable
41+
if (binding.createFlags.hasFlags(core::bitflag(IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_UPDATE_AFTER_BIND_BIT)
42+
| IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_UPDATE_UNUSED_WHILE_PENDING_BIT
43+
| IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_PARTIALLY_BOUND_BIT))
44+
{
45+
allocatableDescriptors += binding.count;
46+
}
47+
m_allocatableRanges.push_back(range);
48+
}
49+
50+
m_addressAllocator = AddrAllocator(
51+
_reservedAllocator.allocate(AddressAllocator::reserved_size(maxAllocatableAlignment, static_cast<size_type>(allocatableDescriptors), args...), _NBL_SIMD_ALIGNMENT),
52+
static_cast<size_type>(allocatableDescriptors), 0u, maxAllocatableAlignment, static_cast<size_type>(allocatableDescriptors), std::forward<Args>(args)...
53+
);
54+
m_reservedAllocator = ReservedAllocator(std::move(_reservedAllocator));
55+
m_reservedSize = allocatableDescriptors;
56+
}
57+
// version with default constructed reserved allocator
58+
template<typename... Args>
59+
explicit inline SubAllocatedDescriptorSet(const std::span<const video::IGPUDescriptorSetLayout::SBinding> bindings,
60+
const value_type maxAllocatableAlignment, Args&&... args) :
61+
SubAllocatedDescriptorSet(bindings,ReservedAllocator(),maxAllocatableAlignment,std::forward<Args>(args)...)
62+
{
63+
}
64+
~SubAllocatedDescriptorSet()
65+
{
66+
auto ptr = reinterpret_cast<const uint8_t*>(core::address_allocator_traits<AddressAllocator>::getReservedSpacePtr(m_addressAllocator));
67+
m_reservedAllocator.deallocate(const_cast<uint8_t*>(ptr),m_reservedSize);
68+
}
69+
70+
// anyone gonna use it?
71+
inline const AddressAllocator& getAddressAllocator() const {return m_addressAllocator;}
72+
73+
//
74+
inline ReservedAllocator& getReservedAllocator() {return m_reservedAllocator;}
75+
76+
// main methods
77+
78+
//! Warning `outAddresses` needs to be primed with `invalid_value` values, otherwise no allocation happens for elements not equal to `invalid_value`
79+
template<typename... Args>
80+
inline void multi_allocate(uint32_t count, value_type* outAddresses, const size_type* byteSizes, const size_type* alignments, const Args&... args)
81+
{
82+
core::address_allocator_traits<AddressAllocator>::multi_alloc_addr(m_addressAllocator,count,outAddresses,byteSizes,alignments,args...);
83+
}
84+
template<typename... Args>
85+
inline void multi_deallocate(Args&&... args)
86+
{
87+
core::address_allocator_traits<AddressAllocator>::multi_free_addr(m_addressAllocator,std::forward<Args>(args)...);
88+
}
89+
90+
// to conform to IBufferAllocator concept
91+
template<typename... Args>
92+
inline value_type allocate(const size_type bytes, const size_type alignment, const Args&... args)
93+
{
94+
value_type retval = invalid_value;
95+
multi_allocate(&retval,&bytes,&alignment,args...);
96+
return retval;
97+
}
98+
template<typename... Args>
99+
inline void deallocate(value_type& allocation, Args&&... args)
100+
{
101+
multi_deallocate(std::forward<Args>(args)...);
102+
allocation = invalid_value;
103+
}
104+
105+
protected:
106+
AddressAllocator m_addressAllocator;
107+
ReservedAllocator m_reservedAllocator;
108+
size_t m_reservedSize; // FIXME: uninitialized variable
109+
110+
struct SubAllocDescriptorSetRange {
111+
uint32_t offset;
112+
video::IGPUDescriptorSetLayout::SBinding binding;
113+
};
114+
std::vector<SubAllocDescriptorSetRange> m_allocatableRanges = {};
115+
};
116+
117+
}
118+
119+
#endif
120+

src/nbl/video/utilities/CPropertyPoolHandler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ CPropertyPoolHandler::CPropertyPoolHandler(core::smart_refctd_ptr<ILogicalDevice
8484
#endif
8585
}
8686

87+
uint64_t getAlignment(uint64_t addr)
88+
{
89+
return addr & 7;
90+
}
8791

8892
bool CPropertyPoolHandler::transferProperties(
8993
IGPUCommandBuffer* const cmdbuf, //IGPUFence* const fence,
@@ -134,6 +138,8 @@ bool CPropertyPoolHandler::transferProperties(
134138
transferRequest.fill = 0; // TODO
135139
transferRequest.srcIndexSizeLog2 = 1u; // TODO
136140
transferRequest.dstIndexSizeLog2 = 1u; // TODO
141+
assert(getAlignment(transferRequest.srcAddr) == 0);
142+
assert(getAlignment(transferRequest.dstAddr) == 0);
137143

138144
maxElements = core::max<uint64_t>(maxElements, srcRequest->elementCount);
139145
}
@@ -147,6 +153,8 @@ bool CPropertyPoolHandler::transferProperties(
147153
pushConstants.endOffset = endDWORD;
148154
pushConstants.transferCommandsAddress = scratchBufferDeviceAddr;
149155
}
156+
assert(getAlignment(scratchBufferDeviceAddr) == 0);
157+
assert(getAlignment(sizeof(TransferRequest)) == 0);
150158
cmdbuf->pushConstants(m_pipeline->getLayout(), asset::IShader::ESS_COMPUTE, 0u, sizeof(pushConstants), &pushConstants);
151159

152160
// dispatch

0 commit comments

Comments
 (0)