layers: Remove VulkanTypedHandle usage from NotifyInvalidate
Since everything in the NotifyInvalidate() call tree is a valid
state object, use BASE_NODE pointers directly instead of relying
on VulkanTypedHandle.node.
Note that CMD_BUFFER_STATE::broken_bindings includes handles for
objects that have been destroyed, so it must continue to use
VulkanTypedHandle.
diff --git a/layers/base_node.h b/layers/base_node.h
index b895197..5f96f64 100644
--- a/layers/base_node.h
+++ b/layers/base_node.h
@@ -47,7 +47,8 @@
class BASE_NODE {
public:
- using BindingsType = layer_data::unordered_set<BASE_NODE*>;
+ using NodeSet = layer_data::unordered_set<BASE_NODE *>;
+ using NodeList = small_vector<BASE_NODE *, 4>;
template <typename Handle>
BASE_NODE(Handle h, VulkanObjectType t) : handle_(h, t, this), destroyed_(false) {}
@@ -62,6 +63,7 @@
bool Destroyed() const { return destroyed_; }
const VulkanTypedHandle &Handle() const { return handle_; }
+ VulkanObjectType Type() const { return handle_.type; }
virtual bool InUse() const {
bool result = false;
@@ -84,23 +86,26 @@
}
void Invalidate(bool unlink = true) {
- LogObjectList invalid_handles(handle_);
+ NodeList invalid_nodes;
+ invalid_nodes.emplace_back(this);
for (auto& node: parent_nodes_) {
- node->NotifyInvalidate(invalid_handles, unlink);
+ node->NotifyInvalidate(invalid_nodes, unlink);
}
if (unlink) {
parent_nodes_.clear();
}
}
protected:
- virtual void NotifyInvalidate(const LogObjectList& invalid_handles, bool unlink) {
+ // NOTE: the entries in invalid_nodes will likely be destroyed & deleted
+ // after the NotifyInvalidate() calls finish.
+ virtual void NotifyInvalidate(const NodeList &invalid_nodes, bool unlink) {
if (parent_nodes_.size() == 0) {
return;
}
- LogObjectList up_handles = invalid_handles;
- up_handles.object_list.emplace_back(handle_);
+ NodeList up_nodes = invalid_nodes;
+ up_nodes.emplace_back(this);
for (auto& node: parent_nodes_) {
- node->NotifyInvalidate(up_handles, unlink);
+ node->NotifyInvalidate(up_nodes, unlink);
}
if (unlink) {
parent_nodes_.clear();
@@ -115,7 +120,7 @@
// Set of immediate parent nodes for this object. For an in-use object, the
// parent nodes should form a tree with the root being a command buffer.
- BindingsType parent_nodes_;
+ NodeSet parent_nodes_;
};
class REFCOUNTED_NODE : public BASE_NODE {
diff --git a/layers/cmd_buffer_state.cpp b/layers/cmd_buffer_state.cpp
index 1279818..1c6b486 100644
--- a/layers/cmd_buffer_state.cpp
+++ b/layers/cmd_buffer_state.cpp
@@ -253,14 +253,16 @@
}
void CMD_BUFFER_STATE::AddChild(BASE_NODE *child_node) {
+ assert(child_node);
if (child_node->AddParent(this)) {
- object_bindings.insert(child_node->Handle());
+ object_bindings.insert(child_node);
}
}
void CMD_BUFFER_STATE::RemoveChild(BASE_NODE *child_node) {
+ assert(child_node);
child_node->RemoveParent(this);
- object_bindings.erase(child_node->Handle());
+ object_bindings.erase(child_node);
}
// Reset the command buffer state
@@ -328,9 +330,7 @@
// Remove object bindings
for (const auto &obj : object_bindings) {
- if (obj.node) {
- obj.node->RemoveParent(this);
- }
+ obj->RemoveParent(this);
}
object_bindings.clear();
@@ -358,9 +358,8 @@
transform_feedback_active = false;
// Remove object bindings
- for (const auto &obj : object_bindings) {
- BASE_NODE *base_obj = obj.node;
- if (base_obj) RemoveChild(base_obj);
+ for (auto *base_obj : object_bindings) {
+ RemoveChild(base_obj);
}
object_bindings.clear();
@@ -451,24 +450,28 @@
BASE_NODE::Destroy();
}
-void CMD_BUFFER_STATE::NotifyInvalidate(const LogObjectList &invalid_handles, bool unlink) {
+void CMD_BUFFER_STATE::NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) {
if (state == CB_RECORDING) {
state = CB_INVALID_INCOMPLETE;
} else if (state == CB_RECORDED) {
state = CB_INVALID_COMPLETE;
}
- assert(!invalid_handles.object_list.empty());
- broken_bindings.emplace(invalid_handles.object_list[0], invalid_handles);
+ assert(!invalid_nodes.empty());
+ LogObjectList log_list;
+ for (auto *obj : invalid_nodes) {
+ log_list.object_list.emplace_back(obj->Handle());
+ }
+ broken_bindings.emplace(invalid_nodes[0]->Handle(), log_list);
if (unlink) {
- for (auto &obj : invalid_handles.object_list) {
+ for (auto *obj : invalid_nodes) {
object_bindings.erase(obj);
- if (obj.type == kVulkanObjectTypeCommandBuffer) {
- linkedCommandBuffers.erase(static_cast<CMD_BUFFER_STATE *>(obj.node));
+ if (obj->Type() == kVulkanObjectTypeCommandBuffer) {
+ linkedCommandBuffers.erase(static_cast<CMD_BUFFER_STATE *>(obj));
}
}
}
- BASE_NODE::NotifyInvalidate(invalid_handles, unlink);
+ BASE_NODE::NotifyInvalidate(invalid_nodes, unlink);
}
const CommandBufferImageLayoutMap& CMD_BUFFER_STATE::GetImageSubresourceLayoutMap() const { return image_layout_map; }
diff --git a/layers/cmd_buffer_state.h b/layers/cmd_buffer_state.h
index 52b7be1..eebb1b1 100644
--- a/layers/cmd_buffer_state.h
+++ b/layers/cmd_buffer_state.h
@@ -262,7 +262,7 @@
layer_data::unordered_set<std::shared_ptr<FRAMEBUFFER_STATE>> framebuffers;
// Unified data structs to track objects bound to this command buffer as well as object
// dependencies that have been broken : either destroyed objects, or updated descriptor sets
- layer_data::unordered_set<VulkanTypedHandle> object_bindings;
+ BASE_NODE::NodeSet object_bindings;
layer_data::unordered_map<VulkanTypedHandle, LogObjectList> broken_bindings;
QFOTransferBarrierSets<QFOBufferTransferBarrier> qfo_transfer_buffer_barriers;
@@ -447,7 +447,7 @@
void Retire(uint32_t perf_submit_pass);
protected:
- void NotifyInvalidate(const LogObjectList &invalid_handles, bool unlink) override;
+ void NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) override;
void UpdateAttachmentsView(const VkRenderPassBeginInfo *pRenderPassBegin);
};
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index be54215..1fc9874 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -3109,21 +3109,28 @@
}
// Ensure that any bound images or buffers created with SHARING_MODE_CONCURRENT have access to the current queue family
- for (const auto &object : pCB->object_bindings) {
- if (object.type == kVulkanObjectTypeImage) {
- auto image_state = object.node ? (IMAGE_STATE *)object.node : GetImageState(object.Cast<VkImage>());
- if (image_state && image_state->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) {
- skip |= ValidImageBufferQueue(pCB, object, queue_state->queueFamilyIndex,
- image_state->createInfo.queueFamilyIndexCount,
- image_state->createInfo.pQueueFamilyIndices);
+ for (const auto *base_node : pCB->object_bindings) {
+ switch (base_node->Type()) {
+ case kVulkanObjectTypeImage: {
+ auto image_state = static_cast<const IMAGE_STATE *>(base_node);
+ if (image_state && image_state->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) {
+ skip |= ValidImageBufferQueue(pCB, image_state->Handle(), queue_state->queueFamilyIndex,
+ image_state->createInfo.queueFamilyIndexCount,
+ image_state->createInfo.pQueueFamilyIndices);
+ }
+ break;
}
- } else if (object.type == kVulkanObjectTypeBuffer) {
- auto buffer_state = object.node ? (BUFFER_STATE *)object.node : GetBufferState(object.Cast<VkBuffer>());
- if (buffer_state && buffer_state->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) {
- skip |= ValidImageBufferQueue(pCB, object, queue_state->queueFamilyIndex,
- buffer_state->createInfo.queueFamilyIndexCount,
- buffer_state->createInfo.pQueueFamilyIndices);
+ case kVulkanObjectTypeBuffer: {
+ auto buffer_state = static_cast<const BUFFER_STATE *>(base_node);
+ if (buffer_state && buffer_state->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) {
+ skip |= ValidImageBufferQueue(pCB, buffer_state->Handle(), queue_state->queueFamilyIndex,
+ buffer_state->createInfo.queueFamilyIndexCount,
+ buffer_state->createInfo.pQueueFamilyIndices);
+ }
+ break;
}
+ default:
+ break;
}
}
}
diff --git a/layers/device_memory_state.h b/layers/device_memory_state.h
index 5f80b3e..d3775c7 100644
--- a/layers/device_memory_state.h
+++ b/layers/device_memory_state.h
@@ -81,7 +81,7 @@
VkDeviceMemory mem() const { return handle_.Cast<VkDeviceMemory>(); }
- const BindingsType &ObjectBindings() const { return parent_nodes_; }
+ const NodeSet &ObjectBindings() const { return parent_nodes_; }
};
// Generic memory binding struct to track objects bound to objects
diff --git a/layers/image_state.cpp b/layers/image_state.cpp
index a4c049c..132c340 100644
--- a/layers/image_state.cpp
+++ b/layers/image_state.cpp
@@ -265,8 +265,8 @@
BINDABLE::Destroy();
}
-void IMAGE_STATE::NotifyInvalidate(const LogObjectList &invalid_handles, bool unlink) {
- BINDABLE::NotifyInvalidate(invalid_handles, unlink);
+void IMAGE_STATE::NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) {
+ BINDABLE::NotifyInvalidate(invalid_nodes, unlink);
if (unlink) {
Unlink();
}
@@ -331,7 +331,7 @@
void IMAGE_STATE::SetMemBinding(std::shared_ptr<DEVICE_MEMORY_STATE> &mem, VkDeviceSize memory_offset) {
if ((createInfo.flags & VK_IMAGE_CREATE_ALIAS_BIT) != 0) {
for (auto *base_node : mem->ObjectBindings()) {
- if (base_node->Handle().type == kVulkanObjectTypeImage) {
+ if (base_node->Type() == kVulkanObjectTypeImage) {
auto other_image = static_cast<IMAGE_STATE *>(base_node);
AddAliasingImage(other_image);
}
@@ -346,7 +346,7 @@
swapchain_image_index = swapchain_index;
bind_swapchain->AddParent(this);
for (auto *base_node : swapchain->ObjectBindings()) {
- if (base_node->Handle().type == kVulkanObjectTypeImage) {
+ if (base_node->Type() == kVulkanObjectTypeImage) {
auto other_image = static_cast<IMAGE_STATE *>(base_node);
if (swapchain_image_index == other_image->swapchain_image_index) {
AddAliasingImage(other_image);
@@ -551,8 +551,8 @@
BASE_NODE::Destroy();
}
-void SWAPCHAIN_NODE::NotifyInvalidate(const LogObjectList &invalid_handles, bool unlink) {
- BASE_NODE::NotifyInvalidate(invalid_handles, unlink);
+void SWAPCHAIN_NODE::NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) {
+ BASE_NODE::NotifyInvalidate(invalid_nodes, unlink);
if (unlink) {
surface = nullptr;
}
diff --git a/layers/image_state.h b/layers/image_state.h
index e8d3bfe..a97dc38 100644
--- a/layers/image_state.h
+++ b/layers/image_state.h
@@ -188,7 +188,7 @@
protected:
void AddAliasingImage(IMAGE_STATE *bound_image);
void Unlink();
- void NotifyInvalidate(const LogObjectList &invalid_handles, bool unlink) override;
+ void NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) override;
};
// State for VkImageView objects.
@@ -268,10 +268,10 @@
void Destroy() override;
- const BindingsType &ObjectBindings() const { return parent_nodes_; }
+ const NodeSet &ObjectBindings() const { return parent_nodes_; }
protected:
- void NotifyInvalidate(const LogObjectList &invalid_handles, bool unlink) override;
+ void NotifyInvalidate(const BASE_NODE::NodeList &invalid_nodes, bool unlink) override;
};
struct GpuQueue {