mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-13 07:08:50 +01:00
[dxvk] Optimize descriptor set binding further
This commit is contained in:
parent
f9e6d8e23a
commit
15cf130369
@ -4161,24 +4161,27 @@ namespace dxvk {
|
||||
|
||||
DxvkBindingMask newBindMask = refBindMask;
|
||||
|
||||
uint32_t layoutSetMask = layout->getSetMask();
|
||||
|
||||
uint32_t dirtySetMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
|
||||
? m_descriptorState.getDirtyGraphicsSets()
|
||||
: m_descriptorState.getDirtyComputeSets();
|
||||
dirtySetMask &= layoutSetMask;
|
||||
|
||||
uint32_t bindingIndex = 0;
|
||||
uint32_t firstUpdated = DxvkDescriptorSets::SetCount;
|
||||
uint32_t firstUpdated = bit::tzcnt(dirtySetMask);
|
||||
|
||||
while (dirtySetMask) {
|
||||
uint32_t setIndex = bit::tzcnt(dirtySetMask);
|
||||
|
||||
for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) {
|
||||
// Initialize binding mask for the current set, only
|
||||
// clear bits if certain resources are actually unbound.
|
||||
uint32_t bindingCount = bindings.getBindingCount(i);
|
||||
uint32_t bindingIndex = layout->getFirstBinding(setIndex);
|
||||
uint32_t bindingCount = bindings.getBindingCount(setIndex);
|
||||
|
||||
if ((dirtySetMask & (1u << i)) || !m_descriptorState.getSet<BindPoint>(i)) {
|
||||
firstUpdated = std::min(firstUpdated, i);
|
||||
newBindMask.setRange(bindingIndex, bindingCount);
|
||||
|
||||
for (uint32_t j = 0; j < bindingCount; j++) {
|
||||
const auto& binding = bindings.getBinding(i, j);
|
||||
const auto& binding = bindings.getBinding(setIndex, j);
|
||||
|
||||
switch (binding.descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER: {
|
||||
@ -4319,26 +4322,29 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
// Create and populate descriptor set with the given descriptors
|
||||
VkDescriptorSet& set = m_descriptorState.getSet<BindPoint>(i);
|
||||
set = allocateDescriptorSet(layout->getSetLayout(i));
|
||||
VkDescriptorSet& set = m_descriptorState.getSet<BindPoint>(setIndex);
|
||||
set = allocateDescriptorSet(layout->getSetLayout(setIndex));
|
||||
|
||||
if (bindingCount) {
|
||||
m_cmd->updateDescriptorSetWithTemplate(set,
|
||||
layout->getSetUpdateTemplate(i), descriptors.data());
|
||||
}
|
||||
layout->getSetUpdateTemplate(setIndex), descriptors.data());
|
||||
|
||||
dirtySetMask &= dirtySetMask - 1;
|
||||
}
|
||||
|
||||
bindingIndex += bindingCount;
|
||||
}
|
||||
// Bind all descriptor sets that need updating
|
||||
uint32_t bindSetMask = layoutSetMask & ~((1u << firstUpdated) - 1);
|
||||
|
||||
// Bind all updated descriptor sets
|
||||
uint32_t setCount = DxvkDescriptorSets::SetCount - firstUpdated;
|
||||
const VkDescriptorSet* setData = &m_descriptorState.getSet<BindPoint>(firstUpdated);
|
||||
while (bindSetMask) {
|
||||
uint32_t setIndex = bit::tzcnt(bindSetMask);
|
||||
|
||||
VkDescriptorSet& set = m_descriptorState.getSet<BindPoint>(setIndex);
|
||||
|
||||
m_cmd->cmdBindDescriptorSets(BindPoint,
|
||||
layout->getPipelineLayout(),
|
||||
firstUpdated, setCount, setData,
|
||||
0, nullptr);
|
||||
setIndex, 1, &set, 0, nullptr);
|
||||
|
||||
bindSetMask &= bindSetMask - 1;
|
||||
}
|
||||
|
||||
// Update pipeline if there are unbound resources
|
||||
if (refBindMask != newBindMask) {
|
||||
|
Loading…
Reference in New Issue
Block a user