Streamline binding access in MVKDescriptorSetLayout.

Use temporary MVKSmallVector of bindings to sort dynamic offset indices.
Use getDescriptor() where in read/write functions.
This commit is contained in:
Bill Hollings 2020-10-21 15:34:10 -04:00
parent 0738e5471b
commit eb81f2b5be
2 changed files with 22 additions and 33 deletions

View File

@ -85,7 +85,7 @@ protected:
void propagateDebugName() override {} void propagateDebugName() override {}
inline uint32_t getDescriptorCount() { return _descriptorCount; } inline uint32_t getDescriptorCount() { return _descriptorCount; }
inline uint32_t getDescriptorIndex(uint32_t binding, uint32_t elementIndex) { return _bindingToDescriptorIndex[binding] + elementIndex; } inline uint32_t getDescriptorIndex(uint32_t binding, uint32_t elementIndex = 0) { return _bindingToDescriptorIndex[binding] + elementIndex; }
inline MVKDescriptorSetLayoutBinding* getBinding(uint32_t binding) { return &_bindings[_bindingToIndex[binding]]; } inline MVKDescriptorSetLayoutBinding* getBinding(uint32_t binding) { return &_bindings[_bindingToIndex[binding]]; }
MVKSmallVector<MVKDescriptorSetLayoutBinding> _bindings; MVKSmallVector<MVKDescriptorSetLayoutBinding> _bindings;
@ -138,7 +138,7 @@ protected:
friend class MVKDescriptorPool; friend class MVKDescriptorPool;
void propagateDebugName() override {} void propagateDebugName() override {}
MVKDescriptor* getDescriptor(uint32_t binding, uint32_t elementIndex); MVKDescriptor* getDescriptor(uint32_t binding, uint32_t elementIndex = 0);
MVKDescriptorSetLayout* _layout; MVKDescriptorSetLayout* _layout;
MVKDescriptorPool* _pool; MVKDescriptorPool* _pool;

View File

@ -172,42 +172,35 @@ MVKDescriptorSetLayout::MVKDescriptorSetLayout(MVKDevice* device,
const VkDescriptorSetLayoutCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device) { const VkDescriptorSetLayoutCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device) {
_isPushDescriptorLayout = (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) != 0; _isPushDescriptorLayout = (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) != 0;
// Create the descriptor layout bindings
_descriptorCount = 0; _descriptorCount = 0;
_bindings.reserve(pCreateInfo->bindingCount); _bindings.reserve(pCreateInfo->bindingCount);
struct SortInfo MVKSmallVector<MVKDescriptorSetLayoutBinding*, 32> dynamicBindings;
{
const VkDescriptorSetLayoutBinding* binding;
uint32_t index;
};
std::vector<SortInfo> dynamicBindings;
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) { for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
auto* pBind = &pCreateInfo->pBindings[i]; auto* pBind = &pCreateInfo->pBindings[i];
_bindings.emplace_back(_device, this, pBind); _bindings.emplace_back(_device, this, pBind);
_bindingToIndex[pBind->binding] = i; _bindingToIndex[pBind->binding] = i;
_bindingToDescriptorIndex[pBind->binding] = _descriptorCount; _bindingToDescriptorIndex[pBind->binding] = _descriptorCount;
_descriptorCount += _bindings.back().getDescriptorCount();
MVKDescriptorSetLayoutBinding* mvkBind = &_bindings.back();
_descriptorCount += mvkBind->getDescriptorCount();
if (pBind->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || if (pBind->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
pBind->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) { pBind->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
dynamicBindings.push_back(SortInfo{ pBind, i }); dynamicBindings.push_back(mvkBind);
} }
} }
// Dynamic offsets are ordered by binding index when given to vkCmdBindDescriptorSets // Dynamic offsets in vkCmdBindDescriptorSets() are ordered by binding number, not by the
// not by the order they are provided in the layout. // order they are provided in the layout. To prepare for this, sort the dynamic bindings by
// So we want to sort by binding, and then count how many dynamic offsets the binding // binding number and assign to each the index it will use into the array of dynamic offsets.
// has so we can assign each binding it's first dynamic offset index
std::sort(dynamicBindings.begin(), dynamicBindings.end(), std::sort(dynamicBindings.begin(), dynamicBindings.end(),
[](const SortInfo &info1, const SortInfo &info2) { [](MVKDescriptorSetLayoutBinding* mvkBind1, MVKDescriptorSetLayoutBinding* mvkBind2) {
return info1.binding->binding < info2.binding->binding; }); return mvkBind1->getBinding() < mvkBind2->getBinding(); });
uint32_t curOffsetIndex = 0; _dynamicDescriptorCount = 0;
for (auto &i : dynamicBindings) { for (auto mvkBind : dynamicBindings) {
_bindings[i.index].setDynamicOffsetIndex(curOffsetIndex); mvkBind->setDynamicOffsetIndex(_dynamicDescriptorCount);
curOffsetIndex += i.binding->descriptorCount; _dynamicDescriptorCount += mvkBind->getDescriptorCount();
} }
_dynamicDescriptorCount = curOffsetIndex;
} }
@ -230,12 +223,10 @@ void MVKDescriptorSet::write(const DescriptorAction* pDescriptorAction,
VkDescriptorType descType = getDescriptorType(pDescriptorAction->dstBinding); VkDescriptorType descType = getDescriptorType(pDescriptorAction->dstBinding);
uint32_t descCnt = pDescriptorAction->descriptorCount; uint32_t descCnt = pDescriptorAction->descriptorCount;
if (descType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) { if (descType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
uint32_t dstStartIdx = _layout->getDescriptorIndex(pDescriptorAction->dstBinding, 0); // For inline buffers dstArrayElement is a byte offset
// For inline buffers we are using the index argument as dst offset not as src descIdx getDescriptor(pDescriptorAction->dstBinding)->write(this, descType, pDescriptorAction->dstArrayElement, stride, pData);
_descriptors[dstStartIdx]->write(this, descType, pDescriptorAction->dstArrayElement, stride, pData);
} else { } else {
uint32_t dstStartIdx = _layout->getDescriptorIndex(pDescriptorAction->dstBinding, uint32_t dstStartIdx = _layout->getDescriptorIndex(pDescriptorAction->dstBinding, pDescriptorAction->dstArrayElement);
pDescriptorAction->dstArrayElement);
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) { for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
_descriptors[dstStartIdx + descIdx]->write(this, descType, descIdx, stride, pData); _descriptors[dstStartIdx + descIdx]->write(this, descType, descIdx, stride, pData);
} }
@ -260,12 +251,10 @@ void MVKDescriptorSet::read(const VkCopyDescriptorSet* pDescriptorCopy,
uint32_t descCnt = pDescriptorCopy->descriptorCount; uint32_t descCnt = pDescriptorCopy->descriptorCount;
if (descType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) { if (descType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
pInlineUniformBlock->dataSize = pDescriptorCopy->descriptorCount; pInlineUniformBlock->dataSize = pDescriptorCopy->descriptorCount;
uint32_t srcStartIdx = _layout->getDescriptorIndex(pDescriptorCopy->srcBinding, 0); // For inline buffers dstArrayElement is a byte offset
// For inline buffers we are using the index argument as src offset not as dst descIdx getDescriptor(pDescriptorCopy->srcBinding)->read(this, descType, pDescriptorCopy->srcArrayElement, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
_descriptors[srcStartIdx]->read(this, descType, pDescriptorCopy->srcArrayElement, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
} else { } else {
uint32_t srcStartIdx = _layout->getDescriptorIndex(pDescriptorCopy->srcBinding, uint32_t srcStartIdx = _layout->getDescriptorIndex(pDescriptorCopy->srcBinding, pDescriptorCopy->srcArrayElement);
pDescriptorCopy->srcArrayElement);
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) { for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
_descriptors[srcStartIdx + descIdx]->read(this, descType, descIdx, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock); _descriptors[srcStartIdx + descIdx]->read(this, descType, descIdx, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
} }