layers: Fix leaking backing sets for push descriptors
We'd previously leak any temporary descriptor set left bound to the
pipeline at the end of the command buffer. Rearrange things so we can
use unique_ptr and assure it's always cleaned up correctly.
diff --git a/layers/buffer_validation.h b/layers/buffer_validation.h
index dbc0127..0bc7dab 100644
--- a/layers/buffer_validation.h
+++ b/layers/buffer_validation.h
@@ -22,6 +22,7 @@
#include "core_validation_types.h"
#include "core_validation_error_enums.h"
+#include "descriptor_sets.h"
#include "vulkan/vk_layer.h"
#include <limits.h>
#include <memory>
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index a56cbe3..3c63430 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -5378,7 +5378,6 @@
if ((last_bound->boundDescriptorSets[set_idx + firstSet] != nullptr) &&
last_bound->boundDescriptorSets[set_idx + firstSet]->IsPushDescriptor()) {
- delete last_bound->push_descriptors[set_idx + firstSet];
last_bound->push_descriptors[set_idx + firstSet] = nullptr;
last_bound->boundDescriptorSets[set_idx + firstSet] = nullptr;
}
@@ -5561,7 +5560,6 @@
"vkCmdPushDescriptorSet called multiple times for set %d in pipeline layout 0x%" PRIxLEAST64 ".", set,
HandleToUint64(layout));
if (cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[set]->IsPushDescriptor()) {
- delete cb_state->lastBound[pipelineBindPoint].push_descriptors[set];
cb_state->lastBound[pipelineBindPoint].push_descriptors[set] = nullptr;
}
}
@@ -5581,10 +5579,10 @@
const VkDescriptorSetLayout desc_set_layout = 0;
auto const shared_ds_layout = std::make_shared<cvdescriptorset::DescriptorSetLayout>(&layout_create_info, desc_set_layout);
- auto new_desc = new cvdescriptorset::DescriptorSet(0, 0, shared_ds_layout, device_data);
+ std::unique_ptr<cvdescriptorset::DescriptorSet> new_desc{new cvdescriptorset::DescriptorSet(0, 0, shared_ds_layout, device_data)};
new_desc->SetPushDescriptor();
- cb_state->lastBound[pipelineBindPoint].push_descriptors[set] = new_desc;
- cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[set] = new_desc;
+ cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[set] = new_desc.get();
+ cb_state->lastBound[pipelineBindPoint].push_descriptors[set] = std::move(new_desc);
}
VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h
index c62fb40..1d4209c 100644
--- a/layers/core_validation_types.h
+++ b/layers/core_validation_types.h
@@ -622,7 +622,7 @@
// Track each set that has been bound
// Ordered bound set tracking where index is set# that given set is bound to
std::vector<cvdescriptorset::DescriptorSet *> boundDescriptorSets;
- std::vector<cvdescriptorset::DescriptorSet *> push_descriptors;
+ std::vector<std::unique_ptr<cvdescriptorset::DescriptorSet>> push_descriptors;
// one dynamic offset per dynamic descriptor bound to this CB
std::vector<std::vector<uint32_t>> dynamicOffsets;