Skip to content

Commit 376d40d

Browse files
author
devsh
committed
Implement Descriptor Set conversion
1 parent 66ccf38 commit 376d40d

File tree

3 files changed

+5
-209
lines changed

3 files changed

+5
-209
lines changed

include/nbl/video/IGPUDescriptorSetLayout.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class IGPUDescriptorSetLayout : public asset::IDescriptorSetLayout<IGPUSampler>,
2424
using base_t = asset::IDescriptorSetLayout<IGPUSampler>;
2525

2626
public:
27+
inline bool needUpdateAfterBindPool() const {return m_hasUpdateAfterBindBindings;}
2728

2829
inline bool versionChangeInvalidatesCommandBuffer() const { return m_versionChangeInvalidatesCommandBuffer; }
2930

@@ -36,6 +37,8 @@ class IGPUDescriptorSetLayout : public asset::IDescriptorSetLayout<IGPUSampler>,
3637
{
3738
for (const auto& binding : _bindings)
3839
{
40+
if (binding.createFlags.hasFlags(SBinding::E_CREATE_FLAGS::ECF_UPDATE_AFTER_BIND_BIT))
41+
m_hasUpdateAfterBindBindings = true;
3942
if (not (binding.createFlags.hasFlags(SBinding::E_CREATE_FLAGS::ECF_UPDATE_AFTER_BIND_BIT) or binding.createFlags.hasFlags(SBinding::E_CREATE_FLAGS::ECF_UPDATE_UNUSED_WHILE_PENDING_BIT)))
4043
{
4144
m_versionChangeInvalidatesCommandBuffer = true;
@@ -46,6 +49,7 @@ class IGPUDescriptorSetLayout : public asset::IDescriptorSetLayout<IGPUSampler>,
4649

4750
virtual ~IGPUDescriptorSetLayout() = default;
4851

52+
bool m_hasUpdateAfterBindBindings = false;
4953
bool m_isPushDescLayout = false;
5054
bool m_versionChangeInvalidatesCommandBuffer = false;
5155
};

include/nbl/video/utilities/IGPUObjectFromAssetConverter.h

Lines changed: 0 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -531,97 +531,6 @@ inline created_gpu_object_array<asset::ICPUImageView> IGPUObjectFromAssetConvert
531531

532532
inline created_gpu_object_array<asset::ICPUDescriptorSet> IGPUObjectFromAssetConverter::create(const asset::ICPUDescriptorSet** const _begin, const asset::ICPUDescriptorSet** const _end, SParams& _params)
533533
{
534-
const auto assetCount = std::distance(_begin, _end);
535-
auto res = core::make_refctd_dynamic_array<created_gpu_object_array<asset::ICPUDescriptorSet> >(assetCount);
536-
537-
struct BindingDescTypePair_t{
538-
uint32_t binding;
539-
asset::IDescriptor::E_TYPE descType;
540-
size_t count;
541-
};
542-
auto isBufferDesc = [](asset::IDescriptor::E_TYPE t) {
543-
using namespace asset;
544-
switch (t) {
545-
case IDescriptor::E_TYPE::ET_UNIFORM_BUFFER: [[fallthrough]];
546-
case IDescriptor::E_TYPE::ET_STORAGE_BUFFER: [[fallthrough]];
547-
case IDescriptor::E_TYPE::ET_UNIFORM_BUFFER_DYNAMIC: [[fallthrough]];
548-
case IDescriptor::E_TYPE::ET_STORAGE_BUFFER_DYNAMIC:
549-
return true;
550-
break;
551-
default:
552-
return false;
553-
break;
554-
}
555-
};
556-
auto isBufviewDesc = [](asset::IDescriptor::E_TYPE t) {
557-
using namespace asset;
558-
return t==IDescriptor::E_TYPE::ET_STORAGE_TEXEL_BUFFER || t==IDescriptor::E_TYPE::ET_UNIFORM_TEXEL_BUFFER;
559-
};
560-
auto isSampledImgViewDesc = [](asset::IDescriptor::E_TYPE t) {
561-
return t==asset::IDescriptor::E_TYPE::ET_COMBINED_IMAGE_SAMPLER;
562-
};
563-
auto isStorageImgDesc = [](asset::IDescriptor::E_TYPE t) {
564-
return t==asset::IDescriptor::E_TYPE::ET_STORAGE_IMAGE;
565-
};
566-
567-
// TODO: Deal with duplication of layouts and any other resource that can be present at different resource tree levels
568-
core::vector<const asset::ICPUDescriptorSetLayout*> cpuLayouts;
569-
cpuLayouts.reserve(assetCount);
570-
uint32_t maxWriteCount = 0ull;
571-
uint32_t descCount = 0ull;
572-
uint32_t bufCount = 0ull;
573-
uint32_t bufviewCount = 0ull;
574-
uint32_t sampledImgViewCount = 0ull;
575-
uint32_t storageImgViewCount = 0ull;
576-
for (ptrdiff_t i=0u; i<assetCount; i++)
577-
{
578-
const asset::ICPUDescriptorSet* cpuds = _begin[i];
579-
cpuLayouts.push_back(cpuds->getLayout());
580-
581-
for (uint32_t t = 0u; t < static_cast<uint32_t>(asset::IDescriptor::E_TYPE::ET_COUNT); ++t)
582-
{
583-
const auto type = static_cast<asset::IDescriptor::E_TYPE>(t);
584-
585-
// Since one binding can have multiple descriptors which will all be updated with a single SWriteDescriptorSet,
586-
// we add the binding count here not the descriptor count.
587-
maxWriteCount += cpuds->getLayout()->getDescriptorRedirect(type).getBindingCount();
588-
589-
const auto count = cpuds->getLayout()->getTotalDescriptorCount(type);
590-
descCount += count;
591-
592-
if (isBufferDesc(type))
593-
bufCount += count;
594-
else if (isBufviewDesc(type))
595-
bufCount += count;
596-
else if (isSampledImgViewDesc(type))
597-
sampledImgViewCount += count;
598-
else if (isStorageImgDesc(type))
599-
storageImgViewCount += count;
600-
}
601-
}
602-
603-
core::vector<asset::ICPUBuffer*> cpuBuffers;
604-
cpuBuffers.reserve(bufCount);
605-
core::vector<asset::ICPUBufferView*> cpuBufviews;
606-
cpuBufviews.reserve(bufviewCount);
607-
core::vector<asset::ICPUImageView*> cpuImgViews;
608-
cpuImgViews.reserve(storageImgViewCount+sampledImgViewCount);
609-
core::vector<asset::ICPUSampler*> cpuSamplers;
610-
cpuSamplers.reserve(sampledImgViewCount);
611-
for (ptrdiff_t i=0u; i<assetCount; i++)
612-
{
613-
const asset::ICPUDescriptorSet* cpuds = _begin[i];
614-
615-
for (uint32_t t = 0u; t < static_cast<uint32_t>(asset::IDescriptor::E_TYPE::ET_COUNT); ++t)
616-
{
617-
const auto type = static_cast<asset::IDescriptor::E_TYPE>(t);
618-
if (cpuds->getDescriptorInfoStorage(type).empty())
619-
continue;
620-
621-
for (uint32_t d = 0u; d < cpuds->getLayout()->getTotalDescriptorCount(type); ++d)
622-
{
623-
auto* info = cpuds->getDescriptorInfoStorage(type).begin() + d;
624-
auto descriptor = info->desc.get();
625534
if (isBufferDesc(type))
626535
{
627536
auto cpuBuf = static_cast<asset::ICPUBuffer*>(descriptor);
@@ -659,123 +568,6 @@ inline created_gpu_object_array<asset::ICPUDescriptorSet> IGPUObjectFromAssetCon
659568
cpuImg->addImageUsageFlags(asset::IImage::EUF_STORAGE_BIT);
660569
cpuImgViews.push_back(cpuImgView);
661570
}
662-
}
663-
}
664-
}
665-
666-
using redirs_t = core::vector<size_t>;
667-
redirs_t layoutRedirs = eliminateDuplicatesAndGenRedirs(cpuLayouts);
668-
redirs_t bufRedirs = eliminateDuplicatesAndGenRedirs(cpuBuffers);
669-
redirs_t bufviewRedirs = eliminateDuplicatesAndGenRedirs(cpuBufviews);
670-
redirs_t imgViewRedirs = eliminateDuplicatesAndGenRedirs(cpuImgViews);
671-
redirs_t smplrRedirs = eliminateDuplicatesAndGenRedirs(cpuSamplers);
672-
673-
auto gpuLayouts = getGPUObjectsFromAssets<asset::ICPUDescriptorSetLayout>(cpuLayouts.data(), cpuLayouts.data()+cpuLayouts.size(), _params);
674-
auto gpuBuffers = getGPUObjectsFromAssets<asset::ICPUBuffer>(cpuBuffers.data(), cpuBuffers.data()+cpuBuffers.size(), _params);
675-
auto gpuBufviews = getGPUObjectsFromAssets<asset::ICPUBufferView>(cpuBufviews.data(), cpuBufviews.data()+cpuBufviews.size(), _params);
676-
auto gpuImgViews = getGPUObjectsFromAssets<asset::ICPUImageView>(cpuImgViews.data(), cpuImgViews.data()+cpuImgViews.size(), _params);
677-
auto gpuSamplers = getGPUObjectsFromAssets<asset::ICPUSampler>(cpuSamplers.data(), cpuSamplers.data()+cpuSamplers.size(), _params);
678-
679-
uint32_t dsCounts[] = {static_cast<uint32_t>(assetCount)};
680-
auto dsPool = _params.device->createDescriptorPoolForDSLayouts(IDescriptorPool::ECF_NONE,&gpuLayouts->begin()->get(),&gpuLayouts->end()->get(), dsCounts);
681-
682-
core::vector<IGPUDescriptorSet::SWriteDescriptorSet> writes(maxWriteCount);
683-
auto write_it = writes.begin();
684-
core::vector<IGPUDescriptorSet::SDescriptorInfo> descInfos(descCount);
685-
{
686-
auto info = descInfos.begin();
687-
//iterators
688-
uint32_t bi = 0u, bvi = 0u, ivi = 0u, si = 0u;
689-
for (ptrdiff_t i = 0u; i < assetCount; i++)
690-
{
691-
IGPUDescriptorSetLayout* gpulayout = gpuLayouts->operator[](layoutRedirs[i]).get();
692-
res->operator[](i) = dsPool->createDescriptorSet(core::smart_refctd_ptr<IGPUDescriptorSetLayout>(gpulayout));
693-
auto gpuds = res->operator[](i).get();
694-
695-
const asset::ICPUDescriptorSet* cpuds = _begin[i];
696-
697-
for (uint32_t t = 0u; t < static_cast<uint32_t>(asset::IDescriptor::E_TYPE::ET_COUNT); ++t)
698-
{
699-
const auto type = static_cast<asset::IDescriptor::E_TYPE>(t);
700-
701-
const auto& descriptorBindingRedirect = cpuds->getLayout()->getDescriptorRedirect(type);
702-
const auto& mutableSamplerBindingRedirect = cpuds->getLayout()->getMutableSamplerRedirect();
703-
704-
for (uint32_t b = 0u; b < descriptorBindingRedirect.getBindingCount(); ++b)
705-
{
706-
write_it->dstSet = gpuds;
707-
write_it->binding = descriptorBindingRedirect.getBinding(asset::ICPUDescriptorSetLayout::CBindingRedirect::storage_range_index_t{ b }).data;
708-
write_it->arrayElement = 0u;
709-
710-
const uint32_t descriptorCount = descriptorBindingRedirect.getCount(asset::ICPUDescriptorSetLayout::CBindingRedirect::storage_range_index_t{ b });
711-
write_it->count = descriptorCount;
712-
write_it->descriptorType = type;
713-
write_it->info = &(*info);
714-
715-
const uint32_t offset = descriptorBindingRedirect.getStorageOffset(asset::ICPUDescriptorSetLayout::CBindingRedirect::storage_range_index_t{ b }).data;
716-
717-
// It is better to use getDescriptorInfoStorage over getDescriptorInfos, because the latter does a binary search
718-
// over the bindings, which is not really required given we have the index of binding number (since we're iterating
719-
// over all the declared bindings).
720-
auto descriptorInfos = cpuds->getDescriptorInfoStorage(type);
721-
722-
// Iterate through each descriptor in this binding to fill the info structs
723-
bool allDescriptorsPresent = true;
724-
for (uint32_t d = 0u; d < descriptorCount; ++d)
725-
{
726-
if (isBufferDesc(type))
727-
{
728-
core::smart_refctd_ptr<IGPUOffsetBufferPair> buffer = bufRedirs[bi] >= gpuBuffers->size() ? nullptr : gpuBuffers->operator[](bufRedirs[bi]);
729-
if (buffer)
730-
{
731-
info->desc = core::smart_refctd_ptr<IGPUBuffer>(buffer->getBuffer());
732-
info->info.buffer.offset = descriptorInfos.begin()[offset+d].info.buffer.offset + buffer->getOffset();
733-
info->info.buffer.size = descriptorInfos.begin()[offset+d].info.buffer.size;
734-
}
735-
else
736-
{
737-
info->desc = nullptr;
738-
info->info.buffer.offset = 0u;
739-
info->info.buffer.size = 0u;
740-
}
741-
++bi;
742-
}
743-
else if (isBufviewDesc(type))
744-
{
745-
info->desc = bufviewRedirs[bvi] >= gpuBufviews->size() ? nullptr : gpuBufviews->operator[](bufviewRedirs[bvi]);
746-
++bvi;
747-
}
748-
else if (isSampledImgViewDesc(type) || isStorageImgDesc(type))
749-
{
750-
info->desc = imgViewRedirs[ivi] >= gpuImgViews->size() ? nullptr : gpuImgViews->operator[](imgViewRedirs[ivi]);
751-
++ivi;
752-
info->info.image.imageLayout = descriptorInfos[offset + d].info.image.imageLayout;
753-
assert(info->info.image.imageLayout != asset::IImage::EL_UNDEFINED);
754-
755-
if (!isStorageImgDesc(type))
756-
{
757-
const bool isMutableSamplerBinding = (mutableSamplerBindingRedirect.findBindingStorageIndex(asset::ICPUDescriptorSetLayout::CBindingRedirect::binding_number_t{ write_it->binding }).data != mutableSamplerBindingRedirect.Invalid);
758-
if (isMutableSamplerBinding)
759-
{
760-
assert(descriptorInfos.begin()[offset + d].info.image.sampler);
761-
info->info.image.sampler = gpuSamplers->operator[](smplrRedirs[si++]);
762-
}
763-
}
764-
}
765-
allDescriptorsPresent = allDescriptorsPresent && info->desc;
766-
info++;
767-
}
768-
769-
if (allDescriptorsPresent)
770-
write_it++;
771-
}
772-
}
773-
}
774-
}
775-
776-
_params.device->updateDescriptorSets(write_it - writes.begin(), writes.data(), 0u, nullptr);
777-
778-
return res;
779571
}
780572

781573
auto IGPUObjectFromAssetConverter::create(const asset::ICPUAccelerationStructure** _begin, const asset::ICPUAccelerationStructure** _end, SParams& _params) -> created_gpu_object_array<asset::ICPUAccelerationStructure>

0 commit comments

Comments
 (0)