layers: Improve DescriptorSet cleanup
Create private helper function InvalidateBoundCmdBuffers() within the
DescriptorSet class to unify invalidate cases due to set being updated
or freed.
Add a destructor for DescriptorSet to make sure that no bound cmd buffers
hang on to deleted set references.
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 780d27d..3e5360b 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -3387,15 +3387,6 @@
}
return skip_call;
}
-static void invalidateBoundCmdBuffers(layer_data *dev_data, cvdescriptorset::DescriptorSet *pSet) {
- // Flag any CBs this set is bound to as INVALID and remove set binding
- for (auto cb_node : pSet->GetBoundCmdBuffers()) {
- cb_node->state = CB_INVALID;
- for (uint32_t i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; ++i) {
- cb_node->lastBound[i].uniqueBoundSets.erase(pSet);
- }
- }
-}
// update DS mappings based on write and copy update arrays
static bool dsUpdate(layer_data *my_data, VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pWDS,
uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pCDS) {
@@ -3505,7 +3496,6 @@
// Free the descriptor set, remove it from setMap and invalidate any cmd buffers that it was bound to
static void freeDescriptorSet(layer_data *dev_data, cvdescriptorset::DescriptorSet *descriptor_set) {
- invalidateBoundCmdBuffers(dev_data, descriptor_set);
dev_data->setMap.erase(descriptor_set->GetSet());
delete descriptor_set;
}
diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp
index 437dcdc..1d9eed6 100644
--- a/layers/descriptor_sets.cpp
+++ b/layers/descriptor_sets.cpp
@@ -324,6 +324,15 @@
}
}
}
+cvdescriptorset::DescriptorSet::~DescriptorSet() {
+ InvalidateBoundCmdBuffers();
+ // Remove link to any cmd buffers
+ for (auto cb : bound_cmd_buffers_) {
+ for (uint32_t i=0; i<VK_PIPELINE_BIND_POINT_RANGE_SIZE; ++i) {
+ cb->lastBound[i].uniqueBoundSets.erase(this);
+ }
+ }
+}
// Is this sets underlying layout compatible with passed in layout according to "Pipeline Layout Compatibility" in spec?
bool cvdescriptorset::DescriptorSet::IsCompatible(const DescriptorSetLayout *layout, std::string *error) const {
return layout->IsCompatible(p_layout_, error);
@@ -452,6 +461,12 @@
p_layout_->FillBindingSet(&binding_set);
return GetStorageUpdates(binding_set, buffer_set, image_set);
}
+// Set is being deleted or updates so invalidate all bound cmd buffers
+void cvdescriptorset::DescriptorSet::InvalidateBoundCmdBuffers() {
+ for (auto cb_node : bound_cmd_buffers_) {
+ cb_node->state = CB_INVALID;
+ }
+}
// Perform write update in given update struct
// If an error occurs, return false and fill in details in error_msg string
bool cvdescriptorset::DescriptorSet::WriteUpdate(debug_report_data *report_data, const VkWriteDescriptorSet *update,
@@ -514,10 +529,7 @@
if (num_updates != 0) {
some_update_ = true;
}
- // Invalidate any bound command buffers
- for (auto cb_node : bound_cmd_buffers_) {
- cb_node->state = CB_INVALID;
- }
+ InvalidateBoundCmdBuffers();
return true;
}
// Copy update
@@ -595,10 +607,7 @@
if (num_updates != 0) {
some_update_ = true;
}
- // Invalidate any bound command buffers
- for (auto cb_node : bound_cmd_buffers_) {
- cb_node->state = CB_INVALID;
- }
+ InvalidateBoundCmdBuffers();
return true;
}
cvdescriptorset::SamplerDescriptor::SamplerDescriptor(
diff --git a/layers/descriptor_sets.h b/layers/descriptor_sets.h
index 5b358d6..5abe45f 100644
--- a/layers/descriptor_sets.h
+++ b/layers/descriptor_sets.h
@@ -290,7 +290,7 @@
const std::unordered_map<VkImageView, VkImageViewCreateInfo> *, const std::unordered_map<VkImage, IMAGE_NODE> *,
const std::unordered_map<VkImage, VkSwapchainKHR> *,
const std::unordered_map<VkSwapchainKHR, SWAPCHAIN_NODE *> *);
- ~DescriptorSet(){};
+ ~DescriptorSet();
// A number of common Get* functions that return data based on layout from which this set was created
uint32_t GetTotalDescriptorCount() const { return p_layout_ ? p_layout_->GetTotalDescriptorCount() : 0; };
uint32_t GetDynamicDescriptorCount() const { return p_layout_ ? p_layout_->GetDynamicDescriptorCount() : 0; };
@@ -351,6 +351,8 @@
private:
bool ValidateUpdate(const VkWriteDescriptorSet *, const uint32_t, std::string *) const;
+ // Private helper to set all bound cmd buffers to INVALID state
+ void InvalidateBoundCmdBuffers();
bool some_update_; // has any part of the set ever been updated?
VkDescriptorSet set_;
uint32_t descriptor_count_; // Count of all descriptors in this set