Skip to content

Commit

Permalink
Merge branch 'suballocdescriptorset' of github.com:Devsh-Graphics-Pro…
Browse files Browse the repository at this point in the history
…gramming/Nabla
  • Loading branch information
devshgraphicsprogramming committed Mar 13, 2024
2 parents f3df85d + aca4c74 commit d0052ac
Show file tree
Hide file tree
Showing 10 changed files with 563 additions and 15 deletions.
6 changes: 6 additions & 0 deletions include/nbl/asset/IDescriptorSetLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ class IDescriptorSetLayout : public virtual core::IReferenceCounted // TODO: tr
return m_stageFlags[index.data];
}

inline core::bitflag<typename SBinding::E_CREATE_FLAGS> getCreateFlags(const storage_range_index_t index) const
{
assert(index.data < m_count);
return m_createFlags[index.data];
}

inline uint32_t getCount(const storage_range_index_t index) const
{
assert(index.data < m_count);
Expand Down
22 changes: 21 additions & 1 deletion include/nbl/core/alloc/address_allocator_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ namespace nbl::core
}
}

static inline void multi_alloc_addr(AddressAlloc& alloc, uint32_t count, size_type* outAddresses, const size_type* bytes,
const size_type alignment, const size_type* hint=nullptr) noexcept
{
for (uint32_t i=0; i<count; i++)
{
if (outAddresses[i]!=AddressAlloc::invalid_address)
continue;

outAddresses[i] = alloc.alloc_addr(bytes[i],alignment,hint ? hint[i]:0ull);
}
}

static inline void multi_free_addr(AddressAlloc& alloc, uint32_t count, const size_type* addr, const size_type* bytes) noexcept
{
for (uint32_t i=0; i<count; i++)
Expand Down Expand Up @@ -186,6 +198,14 @@ namespace nbl::core
alloc,std::min(count-i,maxMultiOps),outAddresses+i,bytes+i,alignment+i,hint ? (hint+i):nullptr);
}

static inline void multi_alloc_addr(AddressAlloc& alloc, uint32_t count, size_type* outAddresses,
const size_type* bytes, const size_type alignment, const size_type* hint=nullptr) noexcept
{
for (uint32_t i=0; i<count; i+=maxMultiOps)
impl::address_allocator_traits_base<AddressAlloc,has_func_multi_alloc_addr<AddressAlloc>::value>::multi_alloc_addr(
alloc,std::min(count-i,maxMultiOps),outAddresses+i,bytes+i,alignment,hint ? (hint+i):nullptr);
}

static inline void multi_free_addr(AddressAlloc& alloc, uint32_t count, const size_type* addr, const size_type* bytes) noexcept
{
for (uint32_t i=0; i<count; i+=maxMultiOps)
Expand Down Expand Up @@ -244,4 +264,4 @@ namespace nbl::core

}

#endif
#endif
35 changes: 23 additions & 12 deletions include/nbl/video/IGPUDescriptorSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,32 @@ class IGPUDescriptorSet : public asset::IDescriptorSet<const IGPUDescriptorSetLa
uint32_t count;
};

struct SDropDescriptorSet
{
IGPUDescriptorSet* dstSet;
uint32_t binding;
uint32_t arrayElement;
uint32_t count;
};

inline uint64_t getVersion() const { return m_version.load(); }
inline IDescriptorPool* getPool() const { return m_pool.get(); }
inline bool isZombie() const { return (m_pool.get() == nullptr); }

// why is this private? nothing it uses is private
// small utility
inline asset::IDescriptor::E_TYPE getBindingType(const uint32_t binding) const
{
for (auto t=0u; t<static_cast<uint32_t>(asset::IDescriptor::E_TYPE::ET_COUNT); t++)
{
const auto type = static_cast<asset::IDescriptor::E_TYPE>(t);
const auto& bindingRedirect = getLayout()->getDescriptorRedirect(type);
if (bindingRedirect.getStorageOffset(redirect_t::binding_number_t{binding}).data!=redirect_t::Invalid)
return type;
}
return asset::IDescriptor::E_TYPE::ET_COUNT;
}

protected:
IGPUDescriptorSet(core::smart_refctd_ptr<const IGPUDescriptorSetLayout>&& _layout, core::smart_refctd_ptr<IDescriptorPool>&& pool, IDescriptorPool::SStorageOffsets&& offsets);
virtual ~IGPUDescriptorSet();
Expand All @@ -61,6 +83,7 @@ class IGPUDescriptorSet : public asset::IDescriptorSet<const IGPUDescriptorSetLa
void processWrite(const IGPUDescriptorSet::SWriteDescriptorSet& write, const asset::IDescriptor::E_TYPE type);
bool validateCopy(const IGPUDescriptorSet::SCopyDescriptorSet& copy) const;
void processCopy(const IGPUDescriptorSet::SCopyDescriptorSet& copy);
void dropDescriptors(const IGPUDescriptorSet::SDropDescriptorSet& drop);

using redirect_t = IGPUDescriptorSetLayout::CBindingRedirect;
// This assumes that descriptors of a particular type in the set will always be contiguous in pool's storage memory, regardless of which binding in the set they belong to.
Expand All @@ -76,18 +99,6 @@ class IGPUDescriptorSet : public asset::IDescriptorSet<const IGPUDescriptorSetLa

return descriptors+localOffset;
}
// small utility
inline asset::IDescriptor::E_TYPE getBindingType(const uint32_t binding) const
{
for (auto t=0u; t<static_cast<uint32_t>(asset::IDescriptor::E_TYPE::ET_COUNT); t++)
{
const auto type = static_cast<asset::IDescriptor::E_TYPE>(t);
const auto& bindingRedirect = getLayout()->getDescriptorRedirect(type);
if (bindingRedirect.getStorageOffset(redirect_t::binding_number_t{binding}).data!=redirect_t::Invalid)
return type;
}
return asset::IDescriptor::E_TYPE::ET_COUNT;
}

inline core::smart_refctd_ptr<IGPUSampler>* getMutableSamplers(const uint32_t binding) const
{
Expand Down
7 changes: 7 additions & 0 deletions include/nbl/video/ILogicalDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,9 @@ class NBL_API2 ILogicalDevice : public core::IReferenceCounted, public IDeviceMe
return updateDescriptorSets({pDescriptorWrites,descriptorWriteCount},{pDescriptorCopies,descriptorCopyCount});
}

// should this be joined together with the existing updateDescriptorSets?
bool nullifyDescriptors(const std::span<const IGPUDescriptorSet::SDropDescriptorSet> dropDescriptors);

//! Renderpasses and Framebuffers
core::smart_refctd_ptr<IGPURenderpass> createRenderpass(const IGPURenderpass::SCreationParams& params);
inline core::smart_refctd_ptr<IGPUFramebuffer> createFramebuffer(IGPUFramebuffer::SCreationParams&& params)
Expand Down Expand Up @@ -865,6 +868,10 @@ class NBL_API2 ILogicalDevice : public core::IReferenceCounted, public IDeviceMe
};
virtual void updateDescriptorSets_impl(const SUpdateDescriptorSetsParams& params) = 0;

// Drops refcounted references of the descriptors in these indices for the descriptor lifetime tracking
// If the nullDescriptor device feature is enabled, this would also write a null descriptor to the descriptor set
virtual void nullifyDescriptors_impl(const std::span<const IGPUDescriptorSet::SDropDescriptorSet> dropDescriptors) = 0;

virtual core::smart_refctd_ptr<IGPURenderpass> createRenderpass_impl(const IGPURenderpass::SCreationParams& params, IGPURenderpass::SCreationParamValidationResult&& validation) = 0;
virtual core::smart_refctd_ptr<IGPUFramebuffer> createFramebuffer_impl(IGPUFramebuffer::SCreationParams&& params) = 0;

Expand Down
Loading

0 comments on commit d0052ac

Please sign in to comment.