From 8d1d3d66e0ab810a3dabf69936cf69454011c923 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 25 Jun 2022 16:02:22 +0200 Subject: [PATCH] [dxvk] Optimize descriptor set binding further --- src/dxvk/dxvk_context.cpp | 46 ++++++++++++++++++-------------------- src/dxvk/dxvk_pipelayout.h | 17 -------------- 2 files changed, 22 insertions(+), 41 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index ff69d2e6f..428503a07 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -85,8 +85,6 @@ namespace dxvk { VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT); - m_descriptorState.clearSets(); - m_state.gp.pipeline = nullptr; m_state.cp.pipeline = nullptr; @@ -4113,10 +4111,10 @@ namespace dxvk { : m_descriptorState.getDirtyComputeSets(); dirtySetMask &= layoutSetMask; - uint32_t firstUpdated = bit::tzcnt(dirtySetMask); + uint32_t bindCount = 0; uint32_t k = 0; - std::array sets = { }; + std::array sets; m_descriptorPool->alloc(layout, dirtySetMask, sets.data()); while (dirtySetMask) { @@ -4130,7 +4128,6 @@ namespace dxvk { newBindMask.setRange(bindingIndex, bindingCount); VkDescriptorSet set = sets[setIndex]; - m_descriptorState.getSet(setIndex) = set; for (uint32_t j = 0; j < bindingCount; j++) { const auto& binding = bindings.getBinding(setIndex, j); @@ -4287,28 +4284,29 @@ namespace dxvk { &m_descriptors[k - bindingCount]); } + bindCount += 1; + + // If the next set is not dirty, update and bind all previously + // updated sets in one go in order to reduce api call overhead. + if (!(dirtySetMask & (1u << (setIndex + 1)))) { + if (!useDescriptorTemplates) { + m_cmd->updateDescriptorSets(k, m_descriptorWrites.data()); + k = 0; + } + + uint32_t firstSet = setIndex + 1 - bindCount; + + m_cmd->cmdBindDescriptorSets(BindPoint, + layout->getPipelineLayout(), + firstSet, bindCount, &sets[firstSet], + 0, nullptr); + + bindCount = 0; + } + dirtySetMask &= dirtySetMask - 1; } - if (!useDescriptorTemplates && k) - m_cmd->updateDescriptorSets(k, m_descriptorWrites.data()); - - // Bind all descriptor sets that need updating - uint32_t bindSetMask = layoutSetMask & ((~0u) << firstUpdated); - - while (bindSetMask) { - uint32_t setIndex = bit::tzcnt(bindSetMask); - uint32_t setCount = bit::tzcnt(~(bindSetMask >> setIndex)); - - VkDescriptorSet* sets = &m_descriptorState.getSet(setIndex); - - m_cmd->cmdBindDescriptorSets(BindPoint, - layout->getPipelineLayout(), - setIndex, setCount, sets, 0, nullptr); - - bindSetMask &= (~0u) << (setIndex + setCount); - } - // Update pipeline if there are unbound resources if (refBindMask != newBindMask) { refBindMask = newBindMask; diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 152af61a7..223652e90 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -523,28 +523,11 @@ namespace dxvk { return result; } - void clearSets() { - for (size_t i = 0; i < m_sets.size(); i++) - m_sets[i] = VK_NULL_HANDLE; - } - - template - VkDescriptorSet& getSet(uint32_t index) { - return m_sets[BindPoint * DxvkDescriptorSets::SetCount + index]; - } - - template - const VkDescriptorSet& getSet(uint32_t index) const { - return m_sets[BindPoint * DxvkDescriptorSets::SetCount + index]; - } - private: VkShaderStageFlags m_dirtyBuffers = 0; VkShaderStageFlags m_dirtyViews = 0; - std::array m_sets; - }; } \ No newline at end of file